* Re: [PATCH 5/7] bridge: allow creating/deleting fdb entries via netlink
From: Stephen Hemminger @ 2011-10-05 19:13 UTC (permalink / raw)
To: Kevin Wilson; +Cc: netdev
In-Reply-To: <CAGXs5wXc0RLE9KbTVVYRa0xuLEKh8mTM7AR7hMBe86HNfDX0HQ@mail.gmail.com>
On Wed, 5 Oct 2011 21:06:54 +0200
Kevin Wilson <wkevils@gmail.com> wrote:
> Hello all,
> I would appreciate if someone can elaborate about "bridge extensions
> to iproute2" mentioned here.
> I downloaded latest iproute2 git tree and did not find it there.
> googling for it did not gave much info about it.
> I will appreciate if someone can tell who develop it, what is the
> status, site, repository tree, etc.
>
> rgs,
> Kevin
The patch to handle this was posted, but is not committed to the tree yet.
--
>From 8e3d00d0602420dadc3d23877a4995ea3d7496c2 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Tue, 4 Oct 2011 09:31:58 -0700
Subject: [PATCH] Add support for bridging control.
This adds a new 'bridge' command which is the bridging equivalent of
the ip command.
---
Makefile | 2 +-
br/.gitignore | 1 +
br/Makefile | 14 +++
br/br_common.h | 13 +++
br/bridge.c | 104 ++++++++++++++++++++++
br/fdb.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++
br/link.c | 142 +++++++++++++++++++++++++++++++
br/monitor.c | 138 ++++++++++++++++++++++++++++++
man/man8/bridge.8 | 177 ++++++++++++++++++++++++++++++++++++++
9 files changed, 835 insertions(+), 1 deletions(-)
create mode 100644 br/.gitignore
create mode 100644 br/Makefile
create mode 100644 br/br_common.h
create mode 100644 br/bridge.c
create mode 100644 br/fdb.c
create mode 100644 br/link.c
create mode 100644 br/monitor.c
create mode 100644 man/man8/bridge.8
diff --git a/Makefile b/Makefile
index d1ace1f..f1d360a 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall
CFLAGS = $(CCOPTS) -I../include $(DEFINES)
YACCFLAGS = -d -t -v
-SUBDIRS=lib ip tc misc netem genl
+SUBDIRS=lib ip tc br misc netem genl
LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a
LDLIBS += $(LIBNETLINK)
diff --git a/br/.gitignore b/br/.gitignore
new file mode 100644
index 0000000..7096907
--- /dev/null
+++ b/br/.gitignore
@@ -0,0 +1 @@
+bridge
diff --git a/br/Makefile b/br/Makefile
new file mode 100644
index 0000000..9a6743e
--- /dev/null
+++ b/br/Makefile
@@ -0,0 +1,14 @@
+BROBJ = bridge.o fdb.o monitor.o link.o
+
+include ../Config
+
+all: bridge
+
+bridge: $(BROBJ) $(LIBNETLINK)
+
+install: all
+ install -m 0755 bridge $(DESTDIR)$(SBINDIR)
+
+clean:
+ rm -f $(BROBJ) bridge
+
diff --git a/br/br_common.h b/br/br_common.h
new file mode 100644
index 0000000..ec1671d
--- /dev/null
+++ b/br/br_common.h
@@ -0,0 +1,13 @@
+extern int print_linkinfo(const struct sockaddr_nl *who,
+ struct nlmsghdr *n,
+ void *arg);
+extern int print_fdb(const struct sockaddr_nl *who,
+ struct nlmsghdr *n, void *arg);
+
+extern int do_fdb(int argc, char **argv);
+extern int do_monitor(int argc, char **argv);
+
+extern int show_stats;
+extern int show_detail;
+extern int timestamp;
+extern struct rtnl_handle rth;
diff --git a/br/bridge.c b/br/bridge.c
new file mode 100644
index 0000000..9e5f69c
--- /dev/null
+++ b/br/bridge.c
@@ -0,0 +1,104 @@
+/*
+ * Get/set/delete bridge with netlink
+ *
+ * Authors: Stephen Hemminger <shemminger@vyatta.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "SNAPSHOT.h"
+#include "utils.h"
+#include "br_common.h"
+
+struct rtnl_handle rth = { .fd = -1 };
+int resolve_hosts;
+int show_stats;
+int show_details;
+int timestamp;
+
+static void usage(void) __attribute__((noreturn));
+
+static void usage(void)
+{
+ fprintf(stderr,
+"Usage: br [ OPTIONS ] OBJECT { COMMAND | help }\n"
+"where OBJECT := { fdb | monitor }\n"
+" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" );
+ exit(-1);
+}
+
+static int do_help(int argc, char **argv)
+{
+ usage();
+}
+
+
+static const struct cmd {
+ const char *cmd;
+ int (*func)(int argc, char **argv);
+} cmds[] = {
+ { "fdb", do_fdb },
+ { "monitor", do_monitor },
+ { "help", do_help },
+ { 0 }
+};
+
+static int do_cmd(const char *argv0, int argc, char **argv)
+{
+ const struct cmd *c;
+
+ for (c = cmds; c->cmd; ++c) {
+ if (matches(argv0, c->cmd) == 0)
+ return c->func(argc-1, argv+1);
+ }
+
+ fprintf(stderr, "Object \"%s\" is unknown, try \"br help\".\n", argv0);
+ return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ while (argc > 1) {
+ char *opt = argv[1];
+ if (strcmp(opt,"--") == 0) {
+ argc--; argv++;
+ break;
+ }
+ if (opt[0] != '-')
+ break;
+ if (opt[1] == '-')
+ opt++;
+
+ if (matches(opt, "-help") == 0) {
+ usage();
+ } else if (matches(opt, "-Version") == 0) {
+ printf("br utility, 0.0\n");
+ exit(0);
+ } else if (matches(opt, "-stats") == 0 ||
+ matches(opt, "-statistics") == 0) {
+ ++show_stats;
+ } else if (matches(opt, "-details") == 0) {
+ ++show_details;
+ } else if (matches(opt, "-timestamp") == 0) {
+ ++timestamp;
+ } else {
+ fprintf(stderr, "Option \"%s\" is unknown, try \"br -help\".\n", opt);
+ exit(-1);
+ }
+ argc--; argv++;
+ }
+
+ if (rtnl_open(&rth, 0) < 0)
+ exit(1);
+
+ if (argc > 1)
+ return do_cmd(argv[1], argc-1, argv+1);
+
+ rtnl_close(&rth);
+ usage();
+}
diff --git a/br/fdb.c b/br/fdb.c
new file mode 100644
index 0000000..d849f97
--- /dev/null
+++ b/br/fdb.c
@@ -0,0 +1,245 @@
+/*
+ * Get/set/delete fdb table with netlink
+ *
+ * Authors: Stephen Hemminger <shemminger@vyatta.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <linux/if_bridge.h>
+#include <linux/if_ether.h>
+#include <linux/neighbour.h>
+#include <string.h>
+
+#include "libnetlink.h"
+#include "br_common.h"
+#include "utils.h"
+
+int filter_index;
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: br fdb { add | del | replace } ADDR dev DEV\n");
+ fprintf(stderr, " br fdb {show} [ dev DEV ]\n");
+ exit(-1);
+}
+
+static const char *state_n2a(unsigned s)
+{
+ static char buf[32];
+
+ if (s & NUD_PERMANENT)
+ return "local";
+
+ if (s & NUD_NOARP)
+ return "static";
+
+ if (s & NUD_STALE)
+ return "stale";
+
+ if (s & NUD_REACHABLE)
+ return "";
+
+ sprintf(buf, "state=%#x", s);
+ return buf;
+}
+
+static char *fmt_time(char *b, size_t l, unsigned long tick)
+{
+ static int hz;
+
+ if (hz == 0)
+ hz = __get_user_hz();
+
+ snprintf(b, l, "%lu.%02lu", tick / hz, ((tick % hz) * hz) / 100);
+ return b;
+}
+
+int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+ FILE *fp = arg;
+ struct ndmsg *r = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+ struct rtattr * tb[NDA_MAX+1];
+ const __u8 *addr = NULL;
+ char b1[32];
+
+ len -= NLMSG_LENGTH(sizeof(*r));
+ if (len < 0) {
+ fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+
+ if (r->ndm_family != AF_BRIDGE)
+ return 0;
+
+ if (filter_index && filter_index != r->ndm_ifindex)
+ return 0;
+
+ parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
+ n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
+
+ if (n->nlmsg_type == RTM_DELNEIGH)
+ fprintf(fp, "Deleted ");
+
+ if (tb[NDA_LLADDR])
+ addr = RTA_DATA(tb[NDA_LLADDR]);
+ else {
+ fprintf(stderr, "missing lladdr\n");
+ return -1;
+ }
+
+ fprintf(fp, "%s\t%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t%s",
+ ll_index_to_name(r->ndm_ifindex),
+ addr[0], addr[1], addr[2],
+ addr[3], addr[4], addr[5],
+ state_n2a(r->ndm_state));
+
+ if (show_stats && tb[NDA_CACHEINFO]) {
+ struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
+
+ fprintf(fp, "\t%8s", fmt_time(b1, sizeof(b1), ci->ndm_updated));
+ fprintf(fp, " %8s", fmt_time(b1, sizeof(b1), ci->ndm_used));
+ }
+ fprintf(fp, "\n");
+ fflush(fp);
+ return 0;
+}
+
+static int fdb_show(int argc, char **argv)
+{
+ char *filter_dev = NULL;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ if (filter_dev)
+ duparg("dev", *argv);
+ filter_dev = *argv;
+ }
+ argc--; argv++;
+ }
+
+ if (filter_dev) {
+ if ((filter_index = if_nametoindex(filter_dev)) == 0) {
+ fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev);
+ return -1;
+ }
+ }
+
+ if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETNEIGH) < 0) {
+ perror("Cannot send dump request");
+ exit(1);
+ }
+
+ printf("port\tmac addr\t\tflags%s\n",
+ show_stats ? "\t updated used" : "");
+
+ if (rtnl_dump_filter(&rth, print_fdb, stdout, NULL, NULL) < 0) {
+ fprintf(stderr, "Dump terminated\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
+static int fdb_modify(int cmd, int flags, int argc, char **argv)
+{
+ struct {
+ struct nlmsghdr n;
+ struct ndmsg ndm;
+ char buf[256];
+ } req;
+ char *addr = NULL;
+ char *d = NULL;
+ char abuf[ETH_ALEN];
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST|flags;
+ req.n.nlmsg_type = cmd;
+ req.ndm.ndm_family = PF_BRIDGE;
+ req.ndm.ndm_state = NUD_NOARP;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ d = *argv;
+ } else if (strcmp(*argv, "local") == 0) {
+ req.ndm.ndm_state = NUD_PERMANENT;
+ } else if (strcmp(*argv, "temp") == 0) {
+ req.ndm.ndm_state = NUD_REACHABLE;
+ } else {
+ if (strcmp(*argv, "to") == 0) {
+ NEXT_ARG();
+ }
+ if (matches(*argv, "help") == 0) {
+ NEXT_ARG();
+ }
+ if (addr)
+ duparg2("to", *argv);
+ addr = *argv;
+ }
+ argc--; argv++;
+ }
+
+ if (d == NULL || addr == NULL) {
+ fprintf(stderr, "Device and address are required arguments.\n");
+ exit(-1);
+ }
+
+ if (sscanf(addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ abuf, abuf+1, abuf+2,
+ abuf+3, abuf+4, abuf+5) != 6) {
+ fprintf(stderr, "Invalid mac address %s\n", addr);
+ exit(-1);
+ }
+
+ addattr_l(&req.n, sizeof(req), NDA_LLADDR, abuf, ETH_ALEN);
+
+ req.ndm.ndm_ifindex = ll_name_to_index(d);
+ if (req.ndm.ndm_ifindex == 0) {
+ fprintf(stderr, "Cannot find device \"%s\"\n", d);
+ return -1;
+ }
+
+ if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
+ exit(2);
+
+ return 0;
+}
+
+int do_fdb(int argc, char **argv)
+{
+ ll_init_map(&rth);
+
+ if (argc > 0) {
+ if (matches(*argv, "add") == 0)
+ return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
+ if (matches(*argv, "change") == 0)
+ return fdb_modify(RTM_NEWNEIGH, NLM_F_REPLACE, argc-1, argv+1);
+
+ if (matches(*argv, "replace") == 0)
+ return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
+ if (matches(*argv, "delete") == 0)
+ return fdb_modify(RTM_DELNEIGH, 0, argc-1, argv+1);
+ if (matches(*argv, "show") == 0 ||
+ matches(*argv, "lst") == 0 ||
+ matches(*argv, "list") == 0)
+ return fdb_show(argc-1, argv+1);
+ if (matches(*argv, "help") == 0)
+ usage();
+ } else
+ return fdb_show(0, NULL);
+
+ fprintf(stderr, "Command \"%s\" is unknown, try \"ip neigh help\".\n", *argv);
+ exit(-1);
+}
diff --git a/br/link.c b/br/link.c
new file mode 100644
index 0000000..1b9541d
--- /dev/null
+++ b/br/link.c
@@ -0,0 +1,142 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <linux/if.h>
+#include <linux/if_bridge.h>
+#include <string.h>
+
+#include "utils.h"
+#include "br_common.h"
+
+static const char *port_states[] = {
+ [BR_STATE_DISABLED] = "disabled",
+ [BR_STATE_LISTENING] = "listening",
+ [BR_STATE_LEARNING] = "learning",
+ [BR_STATE_FORWARDING] = "forwarding",
+ [BR_STATE_BLOCKING] = "blocking",
+};
+
+extern char *if_indextoname (unsigned int __ifindex, char *__ifname);
+
+static void print_link_flags(FILE *fp, unsigned flags)
+{
+ fprintf(fp, "<");
+ if (flags & IFF_UP && !(flags & IFF_RUNNING))
+ fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
+ flags &= ~IFF_RUNNING;
+#define _PF(f) if (flags&IFF_##f) { \
+ flags &= ~IFF_##f ; \
+ fprintf(fp, #f "%s", flags ? "," : ""); }
+ _PF(LOOPBACK);
+ _PF(BROADCAST);
+ _PF(POINTOPOINT);
+ _PF(MULTICAST);
+ _PF(NOARP);
+ _PF(ALLMULTI);
+ _PF(PROMISC);
+ _PF(MASTER);
+ _PF(SLAVE);
+ _PF(DEBUG);
+ _PF(DYNAMIC);
+ _PF(AUTOMEDIA);
+ _PF(PORTSEL);
+ _PF(NOTRAILERS);
+ _PF(UP);
+ _PF(LOWER_UP);
+ _PF(DORMANT);
+ _PF(ECHO);
+#undef _PF
+ if (flags)
+ fprintf(fp, "%x", flags);
+ fprintf(fp, "> ");
+}
+
+static const char *oper_states[] = {
+ "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
+ "TESTING", "DORMANT", "UP"
+};
+
+static void print_operstate(FILE *f, __u8 state)
+{
+ if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
+ fprintf(f, "state %#x ", state);
+ else
+ fprintf(f, "state %s ", oper_states[state]);
+}
+
+int print_linkinfo(const struct sockaddr_nl *who,
+ struct nlmsghdr *n, void *arg)
+{
+ FILE *fp = arg;
+ int len = n->nlmsg_len;
+ struct ifinfomsg *ifi = NLMSG_DATA(n);
+ struct rtattr * tb[IFLA_MAX+1];
+ char b1[IFNAMSIZ];
+
+ len -= NLMSG_LENGTH(sizeof(*ifi));
+ if (len < 0) {
+ fprintf(stderr, "Message too short!\n");
+ return -1;
+ }
+
+ if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC))
+ return 0;
+
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+ if (tb[IFLA_IFNAME] == NULL) {
+ fprintf(stderr, "BUG: nil ifname\n");
+ return -1;
+ }
+
+ if (n->nlmsg_type == RTM_DELLINK)
+ fprintf(fp, "Deleted ");
+
+ fprintf(fp, "%d: %s ", ifi->ifi_index,
+ tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
+
+ if (tb[IFLA_OPERSTATE])
+ print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]));
+
+ if (tb[IFLA_LINK]) {
+ SPRINT_BUF(b1);
+ int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
+
+ if (iflink == 0)
+ fprintf(fp, "@NONE: ");
+ else {
+ fprintf(fp, "@%s: ",
+ if_indextoname(iflink, b1));
+ }
+ } else {
+ fprintf(fp, ": ");
+ }
+
+ print_link_flags(fp, ifi->ifi_flags);
+
+ if (tb[IFLA_MTU])
+ fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
+
+ if (tb[IFLA_MASTER]) {
+ fprintf(fp, "master %s ",
+ if_indextoname(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
+ }
+
+ if (tb[IFLA_PROTINFO]) {
+ uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]);
+ if (state <= BR_STATE_BLOCKING)
+ fprintf(fp, "state %s", port_states[state]);
+ else
+ fprintf(fp, "state (%d)", state);
+ }
+
+
+ fprintf(fp, "\n");
+ fflush(fp);
+ return 0;
+}
diff --git a/br/monitor.c b/br/monitor.c
new file mode 100644
index 0000000..37468e6
--- /dev/null
+++ b/br/monitor.c
@@ -0,0 +1,138 @@
+/*
+ * brmonitor.c "br monitor"
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Stephen Hemminger <shemminger@vyatta.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <linux/if_bridge.h>
+#include <linux/neighbour.h>
+#include <string.h>
+
+#include "utils.h"
+#include "br_common.h"
+
+
+static void usage(void) __attribute__((noreturn));
+int prefix_banner;
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: br monitor\n");
+ exit(-1);
+}
+
+static int show_mark(FILE *fp, const struct nlmsghdr *n)
+{
+ char *tstr;
+ time_t secs = ((__u32*)NLMSG_DATA(n))[0];
+ long usecs = ((__u32*)NLMSG_DATA(n))[1];
+ tstr = asctime(localtime(&secs));
+ tstr[strlen(tstr)-1] = 0;
+ fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
+ return 0;
+}
+
+int accept_msg(const struct sockaddr_nl *who,
+ struct nlmsghdr *n, void *arg)
+{
+ FILE *fp = arg;
+
+ if (timestamp)
+ print_timestamp(fp);
+
+ switch (n->nlmsg_type) {
+ case RTM_NEWLINK:
+ case RTM_DELLINK:
+ if (prefix_banner)
+ fprintf(fp, "[LINK]");
+
+ return print_linkinfo(who, n, arg);
+
+ case RTM_NEWNEIGH:
+ case RTM_DELNEIGH:
+ if (prefix_banner)
+ fprintf(fp, "[NEIGH]");
+ return print_fdb(who, n, arg);
+
+ case 15:
+ return show_mark(fp, n);
+
+ default:
+ return 0;
+ }
+
+
+}
+
+int do_monitor(int argc, char **argv)
+{
+ char *file = NULL;
+ unsigned groups = ~RTMGRP_TC;
+ int llink=0;
+ int lneigh=0;
+
+ rtnl_close(&rth);
+
+ while (argc > 0) {
+ if (matches(*argv, "file") == 0) {
+ NEXT_ARG();
+ file = *argv;
+ } else if (matches(*argv, "link") == 0) {
+ llink=1;
+ groups = 0;
+ } else if (matches(*argv, "fdb") == 0) {
+ lneigh = 1;
+ groups = 0;
+ } else if (strcmp(*argv, "all") == 0) {
+ groups = ~RTMGRP_TC;
+ prefix_banner=1;
+ } else if (matches(*argv, "help") == 0) {
+ usage();
+ } else {
+ fprintf(stderr, "Argument \"%s\" is unknown, try \"br monitor help\".\n", *argv);
+ exit(-1);
+ }
+ argc--; argv++;
+ }
+
+ if (llink)
+ groups |= nl_mgrp(RTNLGRP_LINK);
+
+ if (lneigh) {
+ groups |= nl_mgrp(RTNLGRP_NEIGH);
+ }
+
+ if (file) {
+ FILE *fp;
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ perror("Cannot fopen");
+ exit(-1);
+ }
+ return rtnl_from_file(fp, accept_msg, stdout);
+ }
+
+ if (rtnl_open(&rth, groups) < 0)
+ exit(1);
+ ll_init_map(&rth);
+
+ if (rtnl_listen(&rth, accept_msg, stdout) < 0)
+ exit(2);
+
+ return 0;
+}
+
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
new file mode 100644
index 0000000..8a5d21e
--- /dev/null
+++ b/man/man8/bridge.8
@@ -0,0 +1,177 @@
+.TH BRIDGE 8 "4 October 2011" "iproute2" "Linux"
+.SH NAME
+bridge \- show / manipulate bridge addresses and devices
+.SH SYNOPSIS
+
+.ad l
+.in +8
+.ti -8
+.B bridge
+.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
+.BR help " }"
+.sp
+
+.ti -8
+.IR OBJECT " := { "
+.BR fdb " | " monitor " }"
+.sp
+
+.ti -8
+.IR OPTIONS " := { "
+\fB\-V\fR[\fIersion\fR] |
+\fB\-s\fR[\fItatistics\fR]
+
+.ti -8
+.BR "bridge fdb" " { " add " | " del " | " change " | " replace " } "
+.I LLADDR
+.B dev
+.IR DEV " { "
+.BR local " | " temp " }"
+
+.ti -8
+.BR "bridge fdb" " [ " show " ] [ "
+.B dev
+.IR DEV " ]"
+
+.ti -8
+.BR "bridge monitor" " [ " all " | " neigh " | " link " ]"
+
+.SH OPTIONS
+
+.TP
+.BR "\-V" , " -Version"
+print the version of the
+.B ip
+utility and exit.
+
+.TP
+.BR "\-s" , " \-stats", " \-statistics"
+output more information. If the option
+appears twice or more, the amount of information increases.
+As a rule, the information is statistics or some time values.
+
+
+.SH BRIDGE - COMMAND SYNTAX
+
+.SS
+.I OBJECT
+
+.TP
+.B fdb
+- Forwarding Database entry.
+
+.SS
+.I COMMAND
+
+Specifies the action to perform on the object.
+The set of possible actions depends on the object type.
+As a rule, it is possible to
+.BR "add" , " delete"
+and
+.B show
+(or
+.B list
+) objects, but some objects do not allow all of these operations
+or have some additional commands. The
+.B help
+command is available for all objects. It prints
+out a list of available commands and argument syntax conventions.
+.sp
+If no command is given, some default command is assumed.
+Usually it is
+.B list
+or, if the objects of this class cannot be listed,
+.BR "help" .
+
+.SH bridge fdb - forwarding database management
+
+.B fdb
+objects contain known ethernet addresses fona link.
+
+.P
+The corresponding commands display fdb entries, add new entries,
+and delete old ones.
+
+.SS bridge fdb add - add a new neighbour entry
+.SS bridge fdb change - change an existing entry
+.SS bridge fdb replace - add a new entry or change an existing one
+
+These commands create new neighbour records or update existing ones.
+
+.TP
+.BI "ADDRESS"
+the Ethernet MAC address.
+
+.TP
+.BI dev " NAME"
+the interface to which this address is associated.
+
+.TP
+.in +8
+.B local
+- the address is associated with a local interface on the system
+and is never forwarded.
+.sp
+
+.B temp
+- the address is a dynamic entry, and will be removed if not used.
+.sp
+
+.in -8
+
+.SS bridge fdb delete - delete a forwarding database entry
+This command removes an existing fdb entry.
+
+.PP
+The arguments are the same as with
+.BR "bridge fdb add" ,
+
+.SS bridge fdb show - list forwarding entries.
+
+This commands displays current forwarding table.
+
+.PP
+With the
+.B -statistics
+option, the command becomes verbose. It prints out the last updated
+and last used time for each entry.
+
+.SH bridge monitor - state monitoring
+
+The
+.B bridge
+utility can monitor the state of devices and addresses
+continuously. This option has a slightly different format.
+Namely, the
+.B monitor
+command is the first in the command line and then the object list follows:
+
+.BR "bridge monitor" " [ " all " |"
+.IR LISTofOBJECTS " ]"
+
+.I OBJECT-LIST
+is the list of object types that we want to monitor.
+It may contain
+.BR link ", and " fdb "."
+If no
+.B file
+argument is given,
+.B ip
+opens RTNETLINK, listens on it and dumps state changes in the format
+described in previous sections.
+
+.P
+If a file name is given, it does not listen on RTNETLINK,
+but opens the file containing RTNETLINK messages saved in binary format
+and dumps them. Such a history file can be generated with the
+
+.SH HISTORY
+.B bridge
+was written by Stephen Hemminger and uses kernel facilities added in Linux 3.0
+.SH SEE ALSO
+.BR ip (8)
+.br
+.RB "Please direct bugreports and patches to: " <netdev@vger.kernel.org>
+
+.SH AUTHOR
+Original Manpage by Stephen Hemminger
--
1.7.6.3
^ permalink raw reply related
* Re: [PATCH 5/7] bridge: allow creating/deleting fdb entries via netlink
From: Kevin Wilson @ 2011-10-05 19:06 UTC (permalink / raw)
To: netdev
In-Reply-To: <20110405000537.372602366@vyatta.com>
Hello all,
I would appreciate if someone can elaborate about "bridge extensions
to iproute2" mentioned here.
I downloaded latest iproute2 git tree and did not find it there.
googling for it did not gave much info about it.
I will appreciate if someone can tell who develop it, what is the
status, site, repository tree, etc.
rgs,
Kevin
On Tue, Apr 5, 2011 at 3:03 AM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> Use RTM_NEWNEIGH and RTM_DELNEIGH to allow updating of entries
> in bridge forwarding table. This allows manipulating static entries
> which is not possible with existing tools.
>
> Example (using bridge extensions to iproute2)
> # br fdb add 00:02:03:04:05:06 dev eth0
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> ---
> net/bridge/br_fdb.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++
> net/bridge/br_netlink.c | 3 +
> net/bridge/br_private.h | 2
> 3 files changed, 144 insertions(+)
>
> --- a/net/bridge/br_fdb.c 2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_fdb.c 2011-03-22 10:25:01.057042585 -0700
> @@ -555,3 +555,142 @@ skip:
>
> return skb->len;
> }
> +
> +/* Create new static fdb entry */
> +static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
> + __u16 state)
> +{
> + struct net_bridge *br = source->br;
> + struct hlist_head *head = &br->hash[br_mac_hash(addr)];
> + struct net_bridge_fdb_entry *fdb;
> +
> + fdb = fdb_find(head, addr);
> + if (fdb)
> + return -EEXIST;
> +
> + fdb = fdb_create(head, source, addr);
> + if (!fdb)
> + return -ENOMEM;
> +
> + if (state & NUD_PERMANENT)
> + fdb->is_local = fdb->is_static = 1;
> + else if (state & NUD_NOARP)
> + fdb->is_static = 1;
> + return 0;
> +}
> +
> +/* Add new permanent fdb entry with RTM_NEWNEIGH */
> +int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
> +{
> + struct net *net = sock_net(skb->sk);
> + struct ndmsg *ndm;
> + struct nlattr *tb[NDA_MAX+1];
> + struct net_device *dev;
> + struct net_bridge_port *p;
> + const __u8 *addr;
> + int err;
> +
> + ASSERT_RTNL();
> + err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
> + if (err < 0)
> + return err;
> +
> + ndm = nlmsg_data(nlh);
> + if (ndm->ndm_ifindex == 0) {
> + pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n");
> + return -EINVAL;
> + }
> +
> + dev = __dev_get_by_index(net, ndm->ndm_ifindex);
> + if (dev == NULL) {
> + pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n");
> + return -ENODEV;
> + }
> +
> + if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
> + pr_info("bridge: RTM_NEWNEIGH with invalid address\n");
> + return -EINVAL;
> + }
> +
> + addr = nla_data(tb[NDA_LLADDR]);
> + if (!is_valid_ether_addr(addr)) {
> + pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
> + return -EINVAL;
> + }
> +
> + p = br_port_get_rtnl(dev);
> + if (p == NULL) {
> + pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
> + dev->name);
> + return -EINVAL;
> + }
> +
> + spin_lock_bh(&p->br->hash_lock);
> + err = fdb_add_entry(p, addr, ndm->ndm_state);
> + spin_unlock_bh(&p->br->hash_lock);
> +
> + return err;
> +}
> +
> +static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
> +{
> + struct net_bridge *br = p->br;
> + struct hlist_head *head = &br->hash[br_mac_hash(addr)];
> + struct net_bridge_fdb_entry *fdb;
> +
> + fdb = fdb_find(head, addr);
> + if (!fdb)
> + return -ENOENT;
> +
> + fdb_delete(fdb);
> + return 0;
> +}
> +
> +/* Remove neighbor entry with RTM_DELNEIGH */
> +int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
> +{
> + struct net *net = sock_net(skb->sk);
> + struct ndmsg *ndm;
> + struct net_bridge_port *p;
> + struct nlattr *llattr;
> + const __u8 *addr;
> + struct net_device *dev;
> + int err;
> +
> + ASSERT_RTNL();
> + if (nlmsg_len(nlh) < sizeof(*ndm))
> + return -EINVAL;
> +
> + ndm = nlmsg_data(nlh);
> + if (ndm->ndm_ifindex == 0) {
> + pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n");
> + return -EINVAL;
> + }
> +
> + dev = __dev_get_by_index(net, ndm->ndm_ifindex);
> + if (dev == NULL) {
> + pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n");
> + return -ENODEV;
> + }
> +
> + llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
> + if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
> + pr_info("bridge: RTM_DELNEIGH with invalid address\n");
> + return -EINVAL;
> + }
> +
> + addr = nla_data(llattr);
> +
> + p = br_port_get_rtnl(dev);
> + if (p == NULL) {
> + pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
> + dev->name);
> + return -EINVAL;
> + }
> +
> + spin_lock_bh(&p->br->hash_lock);
> + err = fdb_delete_by_addr(p, addr);
> + spin_unlock_bh(&p->br->hash_lock);
> +
> + return err;
> +}
> --- a/net/bridge/br_netlink.c 2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_netlink.c 2011-03-22 10:25:01.057042585 -0700
> @@ -196,6 +196,9 @@ int __init br_netlink_init(void)
>
> /* Only the first call to __rtnl_register can fail */
> __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL);
> +
> + __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL);
> + __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL);
> __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump);
>
> return 0;
> --- a/net/bridge/br_private.h 2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_private.h 2011-03-22 10:25:01.057042585 -0700
> @@ -355,6 +355,8 @@ extern void br_fdb_update(struct net_bri
> struct net_bridge_port *source,
> const unsigned char *addr);
> extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb);
> +extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
> +extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
>
> /* br_forward.c */
> extern void br_deliver(const struct net_bridge_port *to,
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v2 2/2] virtio-net: Prevent NULL dereference
From: Michael S. Tsirkin @ 2011-10-05 18:59 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317822614.3676.0.camel@lappy>
On Wed, Oct 05, 2011 at 03:50:14PM +0200, Sasha Levin wrote:
> On Mon, 2011-10-03 at 20:40 +0200, Michael S. Tsirkin wrote:
> > On Wed, Sep 28, 2011 at 05:40:55PM +0300, Sasha Levin wrote:
> > > This patch prevents a NULL dereference when the user has passed a length
> > > longer than an actual buffer to virtio-net.
> > >
> > > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > > Cc: virtualization@lists.linux-foundation.org
> > > Cc: netdev@vger.kernel.org
> > > Cc: kvm@vger.kernel.org
> > > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > > ---
> > > drivers/net/virtio_net.c | 12 +++++++++++-
> > > 1 files changed, 11 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index bde0dec..4a53d2a 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -208,12 +208,22 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> > > return NULL;
> > > }
> > >
> > > - while (len) {
> > > + while (len && page) {
> > > set_skb_frag(skb, page, offset, &len);
> > > page = (struct page *)page->private;
> > > offset = 0;
> > > }
> > >
> > > + /*
> > > + * This is the case where we ran out of pages in our linked list, but
> > > + * supposedly have more data to read.
> >
> > Again, let's clarify that this only happens with broken devices.
>
> I think that the code within the if() makes it clear that it isn't the
> regular path.
It doesn't make it clear that this never happens in absence of bugs.
> --
>
> Sasha.
^ permalink raw reply
* Re: [PATCH v2 1/2] virtio-net: Verify page list size before fitting into skb
From: Michael S. Tsirkin @ 2011-10-05 18:59 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317822654.3676.1.camel@lappy>
On Wed, Oct 05, 2011 at 03:50:54PM +0200, Sasha Levin wrote:
> On Mon, 2011-10-03 at 21:04 +0200, Michael S. Tsirkin wrote:
> > On Wed, Sep 28, 2011 at 05:40:54PM +0300, Sasha Levin wrote:
> > > This patch verifies that the length of a buffer stored in a linked list
> > > of pages is small enough to fit into a skb.
> > >
> > > If the size is larger than a max size of a skb, it means that we shouldn't
> > > go ahead building skbs anyway since we won't be able to send the buffer as
> > > the user requested.
> > >
> > > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > > Cc: virtualization@lists.linux-foundation.org
> > > Cc: netdev@vger.kernel.org
> > > Cc: kvm@vger.kernel.org
> > > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > > ---
> > > drivers/net/virtio_net.c | 13 +++++++++++++
> > > 1 files changed, 13 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index 0c7321c..bde0dec 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -195,6 +195,19 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> > > len -= copy;
> > > offset += copy;
> > >
> > > + /*
> > > + * Verify that we can indeed put this data into a skb.
> > > + * This is here to handle cases when the device erroneously
> > > + * tries to receive more than is possible. This is usually
> > > + * the case of a broken device.
> > > + */
> > > + if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) {
> > > + if (net_ratelimit())
> > > + pr_debug("%s: too much data\n", skb->dev->name);
> > > + dev_kfree_skb(skb);
> > > + return NULL;
> > > + }
> > > +
> >
> > BTW, receive_mergeable does
> > pr_debug("%s: packet too long\n", skb->dev->name);
> > skb->dev->stats.rx_length_errors++;
> >
> > which makes sense.
>
> Do you think we should increase rx_length_errors here as well?
this is all debugging tool for devices/drivers, right?
so maybe not worth the noise.
> --
>
> Sasha.
^ permalink raw reply
* Re: [PATCH net-next] Add ethtool -g support to 8139cp
From: Ben Hutchings @ 2011-10-05 18:50 UTC (permalink / raw)
To: Rick Jones; +Cc: netdev
In-Reply-To: <20111005180854.3D68129003A8@tardy>
On Wed, 2011-10-05 at 11:08 -0700, Rick Jones wrote:
> From: Rick Jones <rick.jones2@hp.com>
>
> Add support for reporting ring sizes via ethtool -g to the 8139cp driver.
>
> Signed-off-by: Rick Jones <rick.jones2@hp.com>
>
> ---
>
> diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
> index c77d5af..1dcfe57 100644
> --- a/drivers/net/ethernet/realtek/8139cp.c
> +++ b/drivers/net/ethernet/realtek/8139cp.c
> @@ -1324,6 +1324,19 @@ static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info
> strcpy (info->bus_info, pci_name(cp->pdev));
> }
>
> +static void cp_get_ringparam(struct net_device *dev,
> + struct ethtool_ringparam *ring)
> +{
> + ring->rx_max_pending = CP_RX_RING_SIZE;
> + ring->tx_max_pending = CP_TX_RING_SIZE;
> + ring->rx_mini_max_pending = 0;
> + ring->rx_jumbo_max_pending = 0;
> + ring->rx_pending = CP_RX_RING_SIZE;
> + ring->tx_pending = CP_TX_RING_SIZE;
> + ring->rx_mini_pending = 0;
> + ring->rx_jumbo_pending = 0;
> +}
You generally don't need to set fields to zero in ethtool 'get'
operations, as the ethtool core will initialise the entire structure to
zero.
Ben.
> static int cp_get_regs_len(struct net_device *dev)
> {
> return CP_REGS_SIZE;
> @@ -1525,6 +1538,7 @@ static const struct ethtool_ops cp_ethtool_ops = {
> .get_eeprom_len = cp_get_eeprom_len,
> .get_eeprom = cp_get_eeprom,
> .set_eeprom = cp_set_eeprom,
> + .get_ringparam = cp_get_ringparam,
> };
>
> static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* RCU list entry in ipv6_chk_addr function
From: Eduardo Panisset @ 2011-10-05 18:16 UTC (permalink / raw)
To: netdev
Hi All,
I was looking over ipv6 implementation for kernel 3.0.4.
Shouldn't "hlist_for_each_entry_rcu_bh" be used instead of
"hlist_for_each_entry_rcu" in the function ipv6_chk_addr (file
net/ipv6/addrconf.c) ?
Best Regards,
Eduardo Panisset.
^ permalink raw reply
* [PATCH net-next] Add ethtool -g support to 8139cp
From: Rick Jones @ 2011-10-05 18:08 UTC (permalink / raw)
To: netdev
From: Rick Jones <rick.jones2@hp.com>
Add support for reporting ring sizes via ethtool -g to the 8139cp driver.
Signed-off-by: Rick Jones <rick.jones2@hp.com>
---
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index c77d5af..1dcfe57 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -1324,6 +1324,19 @@ static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info
strcpy (info->bus_info, pci_name(cp->pdev));
}
+static void cp_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
+{
+ ring->rx_max_pending = CP_RX_RING_SIZE;
+ ring->tx_max_pending = CP_TX_RING_SIZE;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = CP_RX_RING_SIZE;
+ ring->tx_pending = CP_TX_RING_SIZE;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
static int cp_get_regs_len(struct net_device *dev)
{
return CP_REGS_SIZE;
@@ -1525,6 +1538,7 @@ static const struct ethtool_ops cp_ethtool_ops = {
.get_eeprom_len = cp_get_eeprom_len,
.get_eeprom = cp_get_eeprom,
.set_eeprom = cp_set_eeprom,
+ .get_ringparam = cp_get_ringparam,
};
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
^ permalink raw reply related
* Re: [net-next 1/1] bna: Multiple Definition and Interface Setup Fix
From: Randy Dunlap @ 2011-10-05 17:09 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, rmody, netdev, linux-next, linux-kernel, linux-scsi,
huangj, adapter_linux_open_src_team, Mauro Carvalho Chehab
In-Reply-To: <20111005192601.fa947a78b188f4a021042a5e@canb.auug.org.au>
On 10/05/11 01:26, Stephen Rothwell wrote:
> On Tue, 04 Oct 2011 23:27:13 -0400 (EDT) David Miller <davem@davemloft.net> wrote:
>>
>> From: Rasesh Mody <rmody@brocade.com>
>> Date: Tue, 4 Oct 2011 19:31:20 -0700
>>
>>> drivers/net/built-in.o: In function `bfa_ioc_ct2_poweron':
>>> (.text+0xcdc90): multiple definition of `bfa_ioc_ct2_poweron'
>>> drivers/scsi/built-in.o:(.text+0x17f9a0): first defined here
>>>
>>> This patch renames bfa_ioc_ct2_poweron() to bfa_nw_ioc_ct2_poweron() to avoid
>>> multiple definition with Brocade scsi driver. It also modifies asic specific
>>> interface setup to allocate MSIX resources at power on in case of 1860 HW with
>>> no asic block and warns if the asic gen is neither BFI_ASIC_GEN_CT nor
>>> BFI_ASIC_GEN_CT2.
>>>
>>> Reported-by: Randy Dunlap <rdunlap@xenotime.net>
>>> Signed-off-by: Rasesh Mody <rmody@brocade.com>
>>
>> Applied, thanks.
Thanks for the patch.
> I also manually applied this to linux-next today.
We could also stand to have this patch applied to linux-next since
it doesn't seem to be merged anywhere else yet: (for drivers/media/video)
http://marc.info/?l=linux-next&m=131741851601754&w=2
--
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
^ permalink raw reply
* IPv4 multicast and mac-vlans acting weird on 3.0.4+
From: Ben Greear @ 2011-10-05 16:46 UTC (permalink / raw)
To: netdev
This is on a hacked 3.0.4 kernel...
I am seeing an issue where an IPv4 mcast receiver will not receive
a 1473 or larger byte mcast message, but will receive a 1472. The difference
being that 1473 ends up being two packets on the wire. It works on
802.1Q VLANs, VETH interfaces and real Ethernet. It does not work
on a mac-vlan hanging off the VETH.
I see packets received on the macvlan in tshark, and they appear correct. No
obvious errors in the macvlan port stats or netstat -s,
and the 'ss' tool doesn't appear to support UDP sockets at all.
So, I'm about to go digging into the code, but if anyone has any
suggestions for places to look, please let me know!
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Ref: UN052-0320
From: Charity Frazier @ 2011-10-05 8:33 UTC (permalink / raw)
^ permalink raw reply
* Re: [PATCH net] mscan: zero accidentally copied register content
From: Oliver Hartkopp @ 2011-10-05 16:10 UTC (permalink / raw)
To: Wolfram Sang; +Cc: Wolfgang Grandegger, Linux Netdev List, Andre Naujoks
In-Reply-To: <20111005155127.GB13794@pengutronix.de>
On 10/05/11 17:51, Wolfram Sang wrote:
> On Wed, Oct 05, 2011 at 05:34:00PM +0200, Oliver Hartkopp wrote:
>> Due to the 16 bit access to mscan registers there's too much data copied to
>> the zero initialized CAN frame when having an odd number of bytes to copy.
>> This patch clears the data byte read from the invalid register entry.
>>
>> Reported-by: Andre Naujoks <nautsch@gmail.com>
>> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
>>
>> ---
>>
>> Hello Wolf[gang|ram],
>>
>> from an error report from Andre Naujoks i tracked down the problem of
>> uninitialized data in (normally) initialized CAN frames to the mscan driver.
>>
>> Regards,
>> Oliver
>>
>>
>> diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
>> index 92feac6..1b60fbe 100644
>> --- a/drivers/net/can/mscan/mscan.c
>> +++ b/drivers/net/can/mscan/mscan.c
>> @@ -327,20 +327,23 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
>> frame->can_dlc = get_can_dlc(in_8(®s->rx.dlr) & 0xf);
>>
>> if (!(frame->can_id & CAN_RTR_FLAG)) {
>> void __iomem *data = ®s->rx.dsr1_0;
>> u16 *payload = (u16 *)frame->data;
>>
>> for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
>> *payload++ = in_be16(data);
>> data += 2 + _MSCAN_RESERVED_DSR_SIZE;
>> }
>> + /* zero accidentally copied register content at odd DLCs */
>> + if (frame->can_dlc & 1)
>> + frame->data[frame->can_dlc] = 0;
>> }
>>
>> out_8(®s->canrflg, MSCAN_RXF);
>
> Nice catch, but wouldn't it be more elegant to never have an invalid byte
> in the first place?
>
> if (can_dlc & 1)
> *payload = in_be16() & mask;
>
Hm, then i would rather think about changing the for() statement and to read
byte-by-byte instead of the current in_be16() usage with the 16bit access
drawbacks ...
Regards,
Oliver
^ permalink raw reply
* Re: [RFC] iproute2: add br command
From: Stephen Hemminger @ 2011-10-05 15:58 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: netdev, John Fastabend
In-Reply-To: <4E8BE63F.4020706@us.ibm.com>
On Tue, 04 Oct 2011 22:08:15 -0700
Sridhar Samudrala <sri@us.ibm.com> wrote:
>
> On Tue, 2011-10-04 at 16:00 -0700, Stephen Hemminger wrote:
> > On Tue, 04 Oct 2011 15:54:07 -0700
> > Sridhar Samudrala<sri@us.ibm.com <mailto:sri@us.ibm.com>> wrote:
> >
> > > On Tue, 2011-10-04 at 15:42 -0700, Stephen Hemminger wrote:
> > > > On Wed, 5 Oct 2011 00:32:31 +0200
> > > > Michał Mirosław<mirqus@gmail.com <mailto:mirqus@gmail.com>> wrote:
> > > >
> > > > > 2011/10/5 Sridhar Samudrala<sri@us.ibm.com <mailto:sri@us.ibm.com>>:
> > > > > > On Tue, 2011-10-04 at 14:07 -0700, Stephen Hemminger wrote:
> > > > > >> On Tue, 04 Oct 2011 09:58:55 -0700
> > > > > >> Andi Kleen<andi@firstfloor.org <mailto:andi@firstfloor.org>> wrote:
> > > > > >> > Stephen Hemminger<shemminger@vyatta.com <mailto:shemminger@vyatta.com>> writes:
> > > > > >> > > This adds a new 'br' command which is the bridging equivalent of
> > > > > >> > > the ip command. More of a demo of how to use netlink and bridging
> > > > > >> > > at this point.
> > > > > >> > Please name it "bridge", not "br"
> > > > > >> Ok, but it breaks the existing pattern.
> > > > > > Is this supposed to replace brctl utility?
> > > > > >
> > > > > > Can we add/delete a bridge and add/delete interfaces to a bridge using
> > > > > > this command?
> > > > > >
> > > > > > If so, why not make it
> > > > > > ip bridge add/del<brname>
> > > > > > ip bridge addif/delif<brname> <ifname>
> > > > >
> > > > > I'll add one more idea:
> > > > >
> > > > > ip link add/del<brname> type bridge
> > > > > ip bridge add/del<brname> <ifname>
> > > > > ip bridge fdb ...
> > > >
> > > > In 3.0 you can already do:
> > > > # ip link add dev br3 type bridge
> This is a new syntax that i think works only for 'bridge' type.
The bridge interface to 'ip link' is nothing special. The same syntax
is available for macvlan, vlan, and bonding.
> All other types require a prefix 'ip link add link'
For vlan:
ip link add link eth0 name eth0.1 type vlan id 1
The reason there is no 'link' parameter when creating a bridge is that
the bridge is a standalone device it is not slaved to an underlying
device.
>
> I think the ip command help text should be updated to include this syntax.
patches accepted...
>
> > > > # ip link set dev eth3 master br3
>
> looks like the command to delete an interface from a bridge is
> ip link set dev eth3 nomaster
>
> Somehow this interface doesn't look all that intuitive.
Propose something better.
> Currently we have 'ip route' and 'ip neigh' to manipulate routing and
> neighbor entry tables. I think 'ip bridge' would be good way to extend
> this to support bridging.
>
> If it is not too late, can we have a interface where all bridge related
> commands can be done using the same prefix.
>
> I think we also should think about how this syntax can be extended to show
> embedded bridges in SR-IOV NICs.
The iproute2 commands in general try to be as close to the
underlying netlink protocol. This makes it less user friendly but smaller,
easier to program. The only part of bridging that is special is the
forwarding database which is similar to the neighbor table.
If I do merge bridging into ip, it would not be as 'ip bridge' but as
another protocol family.
ip -family bridge neigh ...
As far as SR-IOV, the interface in the kernel is netlink and the hardware
people are free to use netlink to use the same messages for SR-IOV, but
haven't.
^ permalink raw reply
* Re: [PATCH net] mscan: zero accidentally copied register content
From: Wolfram Sang @ 2011-10-05 15:51 UTC (permalink / raw)
To: Oliver Hartkopp; +Cc: Wolfgang Grandegger, Linux Netdev List, Andre Naujoks
In-Reply-To: <4E8C78E8.3010605@hartkopp.net>
[-- Attachment #1: Type: text/plain, Size: 1800 bytes --]
On Wed, Oct 05, 2011 at 05:34:00PM +0200, Oliver Hartkopp wrote:
> Due to the 16 bit access to mscan registers there's too much data copied to
> the zero initialized CAN frame when having an odd number of bytes to copy.
> This patch clears the data byte read from the invalid register entry.
>
> Reported-by: Andre Naujoks <nautsch@gmail.com>
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
>
> ---
>
> Hello Wolf[gang|ram],
>
> from an error report from Andre Naujoks i tracked down the problem of
> uninitialized data in (normally) initialized CAN frames to the mscan driver.
>
> Regards,
> Oliver
>
>
> diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
> index 92feac6..1b60fbe 100644
> --- a/drivers/net/can/mscan/mscan.c
> +++ b/drivers/net/can/mscan/mscan.c
> @@ -327,20 +327,23 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
> frame->can_dlc = get_can_dlc(in_8(®s->rx.dlr) & 0xf);
>
> if (!(frame->can_id & CAN_RTR_FLAG)) {
> void __iomem *data = ®s->rx.dsr1_0;
> u16 *payload = (u16 *)frame->data;
>
> for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
> *payload++ = in_be16(data);
> data += 2 + _MSCAN_RESERVED_DSR_SIZE;
> }
> + /* zero accidentally copied register content at odd DLCs */
> + if (frame->can_dlc & 1)
> + frame->data[frame->can_dlc] = 0;
> }
>
> out_8(®s->canrflg, MSCAN_RXF);
Nice catch, but wouldn't it be more elegant to never have an invalid byte
in the first place?
if (can_dlc & 1)
*payload = in_be16() & mask;
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: sky2 bridge hw csum error since 3.0.6
From: Stephen Hemminger @ 2011-10-05 15:38 UTC (permalink / raw)
To: Tobias Powalowski; +Cc: netdev
In-Reply-To: <4E8C5D88.4020500@googlemail.com>
On Wed, 05 Oct 2011 15:37:12 +0200
Tobias Powalowski <tobias.powalowski@googlemail.com> wrote:
> Hi,
> here the log of the new 3.0.6 kernel and my sky2 ethernet card:
> eth0: hw csum failure.
> [ 47.462091] Pid: 0, comm: swapper Not tainted 3.0-ARCH #1
> [ 47.462094] Call Trace:
> [ 47.462097] <IRQ> [<ffffffff81334ca2>] netdev_rx_csum_fault+0x42/0x50
> [ 47.462112] [<ffffffff8132b700>] __skb_checksum_complete_head+0x60/0x70
> [ 47.462116] [<ffffffff8132b721>] __skb_checksum_complete+0x11/0x20
> [ 47.462128] [<ffffffffa05bcfba>] br_multicast_rcv+0x32a/0x1350 [bridge]
> [ 47.462134] [<ffffffff8136758e>] ? ip_rcv+0x21e/0x2f0
> [ 47.462140] [<ffffffff8121aa96>] ? cpumask_next_and+0x36/0x50
> [ 47.462145] [<ffffffff8104a64d>] ? select_task_rq_fair+0x53d/0x9e0
> [ 47.462152] [<ffffffffa05b3fd0>] ? br_handle_local_finish+0x50/0x50
> [bridge]
> [ 47.462159] [<ffffffffa05b3fd0>] ? br_handle_local_finish+0x50/0x50
> [bridge]
> [ 47.462165] [<ffffffffa05b4087>] br_handle_frame_finish+0xb7/0x2a0
> [bridge]
> [ 47.462172] [<ffffffffa05b9e88>]
> br_nf_pre_routing_finish_ipv6+0x108/0x160 [bridge]
> [ 47.462178] [<ffffffffa05ba8dc>] br_nf_pre_routing+0x55c/0x710 [bridge]
> [ 47.462183] [<ffffffff81055b10>] ? try_to_wake_up+0x290/0x290
> [ 47.462188] [<ffffffff8135f7f5>] nf_iterate+0x85/0xc0
> [ 47.462194] [<ffffffffa05b3fd0>] ? br_handle_local_finish+0x50/0x50
> [bridge]
> [ 47.462198] [<ffffffff8135f8ae>] nf_hook_slow+0x7e/0x130
> [ 47.462204] [<ffffffffa05b3fd0>] ? br_handle_local_finish+0x50/0x50
> [bridge]
> [ 47.462210] [<ffffffff81380da1>] ? tcp_rcv_established+0x4d1/0x830
> [ 47.462216] [<ffffffffa05b4420>] br_handle_frame+0x1b0/0x270 [bridge]
> [ 47.462222] [<ffffffffa05b4270>] ?
> br_handle_frame_finish+0x2a0/0x2a0 [bridge]
> [ 47.462227] [<ffffffff8133415e>] __netif_receive_skb+0x16e/0x660
> [ 47.462232] [<ffffffff81334e2d>] netif_receive_skb+0xad/0xc0
> [ 47.462236] [<ffffffff813357a0>] napi_skb_finish+0x50/0x70
> [ 47.462240] [<ffffffff81335875>] napi_gro_receive+0xb5/0xc0
> [ 47.462256] [<ffffffffa028cce3>] sky2_poll+0x693/0xce0 [sky2]
> [ 47.462260] [<ffffffff8136758e>] ? ip_rcv+0x21e/0x2f0
> [ 47.462265] [<ffffffff81334302>] ? __netif_receive_skb+0x312/0x660
> [ 47.462269] [<ffffffff81335109>] net_rx_action+0x149/0x300
> [ 47.462274] [<ffffffff81063e40>] __do_softirq+0xb0/0x270
> [ 47.462279] [<ffffffff813f711c>] call_softirq+0x1c/0x30
> [ 47.462283] [<ffffffff8100da75>] do_softirq+0x65/0xa0
> [ 47.462287] [<ffffffff8106434e>] irq_exit+0x9e/0xc0
> [ 47.462291] [<ffffffff813f7973>] do_IRQ+0x63/0xe0
> [ 47.462296] [<ffffffff813f5653>] common_interrupt+0x13/0x13
> [ 47.462298] <EOI> [<ffffffff81014375>] ? mwait_idle+0x95/0x2e0
> [ 47.462307] [<ffffffff8100a21a>] cpu_idle+0xba/0x100
> [ 47.462311] [<ffffffff813d31f2>] rest_init+0x96/0xa4
> [ 47.462315] [<ffffffff81748c23>] start_kernel+0x3de/0x3eb
> [ 47.462319] [<ffffffff81748347>] x86_64_start_reservations+0x132/0x136
> [ 47.462323] [<ffffffff81748140>] ? early_idt_handlers+0x140/0x140
> [ 47.462327] [<ffffffff8174844d>] x86_64_start_kernel+0x102/0x111
>
> thanks for your help,
> kernel 3.0.4 is not affected by this.
> greetings
> tpowa
There were no changes to the sky2 driver between 3.0.4 and 3.0.6 but there were
changes to multicast tracking. A couple of other pieces of information that might
help. First, what is the chip type:
dmesg | grep sky2
And could you try 'git bisect' to narrow the problem down to a particular
change.
Thanks
P.s: adding netdev list to this to make discussion public.
^ permalink raw reply
* [PATCH net] mscan: zero accidentally copied register content
From: Oliver Hartkopp @ 2011-10-05 15:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Wolfram Sang; +Cc: Linux Netdev List, Andre Naujoks
Due to the 16 bit access to mscan registers there's too much data copied to
the zero initialized CAN frame when having an odd number of bytes to copy.
This patch clears the data byte read from the invalid register entry.
Reported-by: Andre Naujoks <nautsch@gmail.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
Hello Wolf[gang|ram],
from an error report from Andre Naujoks i tracked down the problem of
uninitialized data in (normally) initialized CAN frames to the mscan driver.
Regards,
Oliver
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 92feac6..1b60fbe 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -327,20 +327,23 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
frame->can_dlc = get_can_dlc(in_8(®s->rx.dlr) & 0xf);
if (!(frame->can_id & CAN_RTR_FLAG)) {
void __iomem *data = ®s->rx.dsr1_0;
u16 *payload = (u16 *)frame->data;
for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
*payload++ = in_be16(data);
data += 2 + _MSCAN_RESERVED_DSR_SIZE;
}
+ /* zero accidentally copied register content at odd DLCs */
+ if (frame->can_dlc & 1)
+ frame->data[frame->can_dlc] = 0;
}
out_8(®s->canrflg, MSCAN_RXF);
}
static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
u8 canrflg)
{
struct mscan_priv *priv = netdev_priv(dev);
struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
^ permalink raw reply related
* Re: big picture UDP/IP performance question re 2.6.18 -> 2.6.32
From: Peter Zijlstra @ 2011-10-05 15:33 UTC (permalink / raw)
To: Christoph Lameter
Cc: starlight, Eric Dumazet, linux-kernel, netdev, Willy Tarreau,
Ingo Molnar
In-Reply-To: <alpine.DEB.2.00.1110050915160.30467@router.home>
On Wed, 2011-10-05 at 09:26 -0500, Christoph Lameter wrote:
>
> > Also, for latency, we've got ftrace and a latencytracer, provide traces
> > that illustrate your fail.
>
> We would need a backport of both to a kernel version that works with
> reasonable latencies so that we can figure out what caused these
> regressions for this particular case. Disabling network and kernel
> features usually gives you better performance but there are a lot of
> things in the hot paths these days that can not be disabled.
Well can can also just take the status quo and use tools like ftrace and
perf to find out what your hot paths are and where you're spending time.
On -rt we use the (irq)latencytracer a _lot_ to find problems, a
detailed function trace of WTH the kernel thinks its doing helps a lot
with trying to fix it.
Things like cyclictest are also useful to find application level
latencies, it can trace the entire latency path if needed.
Kernel level profiles are also a great tool to find out where you're
spending your time.
^ permalink raw reply
* Re: big picture UDP/IP performance question re 2.6.18 -> 2.6.32
From: Andi Kleen @ 2011-10-05 15:12 UTC (permalink / raw)
To: Christoph Lameter
Cc: Peter Zijlstra, starlight, Eric Dumazet, linux-kernel, netdev,
Willy Tarreau, Ingo Molnar
In-Reply-To: <alpine.DEB.2.00.1110050915160.30467@router.home>
Christoph Lameter <cl@gentwo.org> writes:
> On Wed, 5 Oct 2011, Peter Zijlstra wrote:
>
>> Clearly none of the tests being ran on a regular basis, by for instance
>> the Intel regression team, covers your needs. Start by fixing that.
>
> The most commonly run, the aged old tests contained in the AIM9 suite,
> have consistently shown these regressions over long years and they have
> been brought up repeatedly in numerous discussions. This is pervasive
> thoughout the OS hotpaths. Just look at how the page fault latencies
> change over time. Take a modern machine and then run successively older
> kernel versions on it. You will see performance getting better and
> latencies becoming smaller.
One of the reason the Intel tests fix problems is that Alex and Tim
and others look into them and track down regressions. If you see
a new problem during your testing you should do the same.
This actually helps.
It doesn't need to be a full analysis/patch, even just posting some detailed
information on a new regression is useful.
For example one tool I found useful is to just enable the function
graph tracer and look at the latencies of functions in that path
during the test.
If something changes dramatically it's relatively easy to point to.
So for example if you see context switch changing it should not
be that difficult to do such a trace and at least point to the guilty
functions and post a mail.
>> Also, for latency, we've got ftrace and a latencytracer, provide traces
>> that illustrate your fail.
>
> We would need a backport of both to a kernel version that works with
> reasonable latencies so that we can figure out what caused these
> regressions for this particular case. Disabling network and kernel
> features usually gives you better performance but there are a lot of
> things in the hot paths these days that can not be disabled.
Please do function traces and point fingers at slow things in hotpath.
The more the merrier. Post a list of a shame!
-Andi
--
ak@linux.intel.com -- Speaking for myself only
^ permalink raw reply
* Re: big picture UDP/IP performance question re 2.6.18 -> 2.6.32
From: starlight @ 2011-10-05 15:12 UTC (permalink / raw)
To: Peter Zijlstra, Christoph Lameter
Cc: Eric Dumazet, linux-kernel, netdev, Willy Tarreau, Ingo Molnar
In-Reply-To: <1317820942.6766.26.camel@twins>
At 03:22 PM 10/5/2011 +0200, Peter Zijlstra wrote:
>On Tue, 2011-10-04 at 14:16 -0500, Christoph Lameter wrote:
>I suppose all this testing and feedback we receive
>from you really helps us keep the performance
>levels you want.. Oh wait, that's 0.
Well I have to admit that I've looked into the
future (i.e. tested kernel.org releases) only on
occasion. To the extent that performance wasn't
looking great I harbored an apparently over
optimistic hope that things would get tuned/fixed
in the process somewhere. In particular I was
thinking that RH might do something impressive
with RHEL 6 where Novell failed with SLES 11.
However, if anything the downstream is fiddling
less and less with the kernel as it becomes ever
more complex.
>Clearly none of the tests being ran on a regular
>basis, by for instance the Intel regression team,
>covers your needs. Start by fixing that.
I could create a test case. It's quite a lot more
than trivial, but not ridiculous either. That UDP
is broken on everything past 2.6.27 may goad me
into the effort. Have had a fairly excellent
experience WRT the hugepage kernel corruption bugs
I reported 18 months or so ago. Not only did the
kernel developers fix them, the fixes made it
downstream into RHEL fairly quickly. So that does
encourage me.
^ permalink raw reply
* Re: big picture UDP/IP performance question re 2.6.18 -> 2.6.32
From: Christoph Lameter @ 2011-10-05 14:26 UTC (permalink / raw)
To: Peter Zijlstra
Cc: starlight, Eric Dumazet, linux-kernel, netdev, Willy Tarreau,
Ingo Molnar
In-Reply-To: <1317820942.6766.26.camel@twins>
On Wed, 5 Oct 2011, Peter Zijlstra wrote:
> Clearly none of the tests being ran on a regular basis, by for instance
> the Intel regression team, covers your needs. Start by fixing that.
The most commonly run, the aged old tests contained in the AIM9 suite,
have consistently shown these regressions over long years and they have
been brought up repeatedly in numerous discussions. This is pervasive
thoughout the OS hotpaths. Just look at how the page fault latencies
change over time. Take a modern machine and then run successively older
kernel versions on it. You will see performance getting better and
latencies becoming smaller.
> Also, for latency, we've got ftrace and a latencytracer, provide traces
> that illustrate your fail.
We would need a backport of both to a kernel version that works with
reasonable latencies so that we can figure out what caused these
regressions for this particular case. Disabling network and kernel
features usually gives you better performance but there are a lot of
things in the hot paths these days that can not be disabled.
^ permalink raw reply
* [PATCH] route: fix ICMP redirect validation
From: Flavio Leitner @ 2011-10-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Flavio Leitner
The commit f39925dbde7788cfb96419c0f092b086aa325c0f
(ipv4: Cache learned redirect information in inetpeer.)
removed some ICMP packet validations which are required by
RFC 1122, section 3.2.2.2:
...
A Redirect message SHOULD be silently discarded if the new
gateway address it specifies is not on the same connected
(sub-) net through which the Redirect arrived [INTRO:2,
Appendix A], or if the source of the Redirect is not the
current first-hop gateway for the specified destination (see
Section 3.3.1).
Signed-off-by: Flavio Leitner <fbl@redhat.com>
---
net/ipv4/route.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 26c77e1..1c11f28 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1308,7 +1308,12 @@ static void rt_del(unsigned hash, struct rtable *rt)
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
__be32 saddr, struct net_device *dev)
{
+ int s, i;
struct in_device *in_dev = __in_dev_get_rcu(dev);
+ struct rtable *rth;
+ struct rtable __rcu **rthp;
+ __be32 skeys[2] = { saddr, 0 };
+ int ikeys[2] = { dev->ifindex, 0 };
struct inet_peer *peer;
struct net *net;
@@ -1321,6 +1326,9 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
ipv4_is_zeronet(new_gw))
goto reject_redirect;
+ if (!rt_caching(net))
+ goto reject_redirect;;
+
if (!IN_DEV_SHARED_MEDIA(in_dev)) {
if (!inet_addr_onlink(in_dev, new_gw, old_gw))
goto reject_redirect;
@@ -1331,13 +1339,42 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
goto reject_redirect;
}
- peer = inet_getpeer_v4(daddr, 1);
- if (peer) {
- peer->redirect_learned.a4 = new_gw;
+ for (s = 0; s < 2; s++) {
+ for (i = 0; i < 2; i++) {
+ unsigned int hash = rt_hash(daddr, skeys[s],
+ ikeys[i], rt_genid(net));
- inet_putpeer(peer);
+ rthp=&rt_hash_table[hash].chain;
- atomic_inc(&__rt_peer_genid);
+ while ((rth = rcu_dereference(*rthp)) != NULL) {
+
+ if (rth->rt_key_dst != daddr ||
+ rth->rt_key_src != skeys[s] ||
+ rth->rt_oif != ikeys[i] ||
+ rt_is_input_route(rth) ||
+ rt_is_expired(rth) ||
+ !net_eq(dev_net(rth->dst.dev), net)) {
+ rthp = &rth->dst.rt_next;
+ continue;
+ }
+
+ if (rth->rt_dst != daddr ||
+ rth->rt_src != saddr ||
+ rth->rt_gateway != old_gw ||
+ rth->dst.dev != dev ||
+ rth->dst.error)
+ break;
+
+ peer = inet_getpeer_v4(daddr, 1);
+ if (peer) {
+ peer->redirect_learned.a4 = new_gw;
+ inet_putpeer(peer);
+ atomic_inc(&__rt_peer_genid);
+ }
+
+ break;
+ }
+ }
}
return;
--
1.7.6
^ permalink raw reply related
* Re: [PATCH] net-proc: expose the tos values in /proc/net/[tcp|udp]
From: MuraliRaja Muniraju @ 2011-10-05 14:09 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, kuznet, jmorris, yoshfuji, kaber, netdev,
linux-kernel
In-Reply-To: <1317807270.2473.35.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Hi Eric,
I am trying one more approach of adding a new attribute to the
inet_diag extension to expose the tos values. Hence with this approach
tcp tos problem would be solved. When udp would also be supported via
netlink and will be using inet_diag, it would be just be publishing
the tos values in the new extension added. Can you let me know your
thoughts on the following patch.
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -97,9 +97,10 @@ enum {
INET_DIAG_INFO,
INET_DIAG_VEGASINFO,
INET_DIAG_CONG,
+ INET_DIAG_TOS,
};
-#define INET_DIAG_MAX INET_DIAG_CONG
+#define INET_DIAG_MAX INET_DIAG_TOS
/* INET_DIAG_MEM */
@@ -120,6 +121,13 @@ struct tcpvegas_info {
__u32 tcpv_minrtt;
};
+/* INET_DIAG_TOS */
+
+struct inet_diag_tos {
+ __u8 idiag_tos;
+ __u8 idiag_reserved[3];
+};
+
#ifdef __KERNEL__
struct sock;
struct inet_hashinfo;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index e5fa2dd..abdd606 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -82,6 +82,7 @@ static int inet_csk_diag_fill(struct sock *sk,
struct nlmsghdr *nlh;
void *info = NULL;
struct inet_diag_meminfo *minfo = NULL;
+ struct inet_diag_tos *tos = NULL;
unsigned char *b = skb_tail_pointer(skb);
const struct inet_diag_handler *handler;
@@ -108,6 +109,9 @@ static int inet_csk_diag_fill(struct sock *sk,
icsk->icsk_ca_ops->name);
}
+ if (ext & (1 << (INET_DIAG_TOS - 1)))
+ tos = INET_DIAG_PUT(skb, INET_DIAG_TOS, sizeof(*tos));
+
r->idiag_family = sk->sk_family;
r->idiag_state = sk->sk_state;
r->idiag_timer = 0;
@@ -169,6 +173,9 @@ static int inet_csk_diag_fill(struct sock *sk,
icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
icsk->icsk_ca_ops->get_info(sk, ext, skb);
+ if (tos)
+ tos->idiag_tos = inet->tos;
+
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
Thanks,
Murali
On Wed, Oct 5, 2011 at 2:34 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mardi 04 octobre 2011 à 10:38 -0700, MuraliRaja Muniraju a écrit :
>> I shall make the changes by exposing the tos values via the
>> netlink as suggested. I had a doubt is I have to modify the
>> inet_diag_sockid or export it via a new option. I am considering
>> that adding into inet_diag_sockid is better because the latter is a
>> bit of a over kill for a single value to be exposed and it also seems
>> to be logical fit.
>> Can you let me know your thoughts on this.
>
> I believe you could add one "u32 tos" to struct tcp_info
>
> [ It wont solve the UDP case, since "ss -u" still dumps /proc/net/udp
> and /proc/net/udp6 ]
>
> Following patch should handle tcp/dccp ipv4/ipv6
>
> diff --git a/include/linux/tcp.h b/include/linux/tcp.h
> index 7f59ee9..eec6f3b 100644
> --- a/include/linux/tcp.h
> +++ b/include/linux/tcp.h
> @@ -167,6 +167,7 @@ struct tcp_info {
> __u32 tcpi_rcv_space;
>
> __u32 tcpi_total_retrans;
> + __u32 tos;
> };
>
> /* for TCP_MD5SIG socket option */
> diff --git a/net/dccp/diag.c b/net/dccp/diag.c
> index b21f261..70d9498 100644
> --- a/net/dccp/diag.c
> +++ b/net/dccp/diag.c
> @@ -37,6 +37,7 @@ static void dccp_get_info(struct sock *sk, struct tcp_info *info)
>
> if (dp->dccps_hc_tx_ccid != NULL)
> ccid_hc_tx_get_info(dp->dccps_hc_tx_ccid, sk, info);
> + info->tos = inet_sk(sk)->tos;
> }
>
> static void dccp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 4c0da24..b24c3d8 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -2493,6 +2493,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
> info->tcpi_rcv_space = tp->rcvq_space.space;
>
> info->tcpi_total_retrans = tp->total_retrans;
> + info->tos = inet_sk(sk)->tos;
> }
> EXPORT_SYMBOL_GPL(tcp_get_info);
>
>
>
>
--
Thanks,
Murali
^ permalink raw reply related
* Re: xfrm warning by mip6d
From: Eric Dumazet @ 2011-10-05 13:55 UTC (permalink / raw)
To: András Takács; +Cc: netdev
In-Reply-To: <34287764-C788-4718-BDD8-8B4DC98FE9F4@wakoond.hu>
Le mercredi 05 octobre 2011 à 15:32 +0200, András Takács a écrit :
> Thanks for the help. I added this two skb_dst_force calls to my kernel source, but unfortunately it didn't solved the problem.
>
> I know it's just a warning message, but I would be happy, if I could fix it.
>
> Does anybody have any other idea?
Is a more recent kernel issuing the same error ?
^ permalink raw reply
* RE: netfilter: Use proper rwlock init function
From: Hans Schillström @ 2011-10-05 13:54 UTC (permalink / raw)
To: Thomas Gleixner, netdev@vger.kernel.org, Julian Anastasov,
horms@verge.net.au
Cc: David Miller
In-Reply-To: <alpine.LFD.2.02.1110051522410.18778@ionos>
Hello Simon,
you can drop my "fix lockdep warning" patch
since Thomas patch is identical to what I prepared to send...
>Replace the open coded initialization with the init function.
>
>Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Ack-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
>---
> net/netfilter/ipvs/ip_vs_ctl.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>Index: linux-2.6/net/netfilter/ipvs/ip_vs_ctl.c
>===================================================================
>--- linux-2.6.orig/net/netfilter/ipvs/ip_vs_ctl.c
>+++ linux-2.6/net/netfilter/ipvs/ip_vs_ctl.c
>@@ -3679,7 +3679,7 @@ int __net_init __ip_vs_control_init(stru
> int idx;
> struct netns_ipvs *ipvs = net_ipvs(net);
>
>- ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock);
>+ rwlock_init(&ipvs->rs_lock);
>
> /* Initialize rs_table */
> for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++)
Thanks
Hans
^ permalink raw reply
* Re: [PATCH v2 2/2] virtio-net: Prevent NULL dereference
From: Sasha Levin @ 2011-10-05 13:50 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <20111003184037.GA22427@redhat.com>
On Mon, 2011-10-03 at 20:40 +0200, Michael S. Tsirkin wrote:
> On Wed, Sep 28, 2011 at 05:40:55PM +0300, Sasha Levin wrote:
> > This patch prevents a NULL dereference when the user has passed a length
> > longer than an actual buffer to virtio-net.
> >
> > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > Cc: virtualization@lists.linux-foundation.org
> > Cc: netdev@vger.kernel.org
> > Cc: kvm@vger.kernel.org
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > ---
> > drivers/net/virtio_net.c | 12 +++++++++++-
> > 1 files changed, 11 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index bde0dec..4a53d2a 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -208,12 +208,22 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> > return NULL;
> > }
> >
> > - while (len) {
> > + while (len && page) {
> > set_skb_frag(skb, page, offset, &len);
> > page = (struct page *)page->private;
> > offset = 0;
> > }
> >
> > + /*
> > + * This is the case where we ran out of pages in our linked list, but
> > + * supposedly have more data to read.
>
> Again, let's clarify that this only happens with broken devices.
I think that the code within the if() makes it clear that it isn't the
regular path.
--
Sasha.
^ permalink raw reply
* Re: [PATCH] SELinux: Fix RCU deref check warning in sel_netport_insert()
From: David Howells @ 2011-10-05 13:32 UTC (permalink / raw)
To: Paul Moore; +Cc: dhowells, selinux, netdev
In-Reply-To: <2230709.7n5noARWFd@sifl>
Paul Moore <paul@paul-moore.com> wrote:
> We should probably do the same for the security/selinux/netif.c as it uses
> the same logic; David is this something you want to tackle?
netif.c doesn't use any rcu_dereference*() function directly, though it does
use list_for_each_entry_rcu(). However, I'm not sure that's a problem. What
is it you're referring to?
David
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox