* Re: Trying to implement secondary loopback
From: Martitz, Thomas @ 2013-03-13 20:38 UTC (permalink / raw)
To: richard -rw- weinberger
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
herbert@gondor.apana.org.au, ebiederm@xmission.com
In-Reply-To: <CAFLxGvxcyDVwC-iys6UdKMBB6u3UQx6s7-mwm5caoNu=N7rmeA@mail.gmail.com>
>
> ________________________________________
> Von: richard -rw- weinberger [richard.weinberger@gmail.com]
> Gesendet: Mittwoch, 13. März 2013 12:13
> An: Martitz, Thomas
> Cc: netdev@vger.kernel.org; davem@davemloft.net; edumazet@google.com; herbert@gondor.apana.org.au; ebiederm@xmission.com
> Betreff: Re: Trying to implement secondary loopback
>
> >
> > So my questions are:
> > * Is this on purpose/expected?
> > * Is there anyway around it so that I can have a custom loopback interface
> > without touching lo's functionality.
> > * Generally, what's the proper way (if any) implement a secondary loopback
> > interface?
>
> The only really question that matters is, why do you need a second
> loopback interface?
> Why can't you use any other pseudo interface?
>
What pseudo interface do you mean? I'm not aware of alternative pseudo interfaces.
I'm developing a NIC and a driver for it. Thus I'm implementing the interface. I'm trying to implement an interface that does exactly do what loopback does except that I want to extend the loopback path to PCIe. This is for testing & validation purposes.
I tried to implement an interface that's doesn't advertise as such. But the data transfer didn't go through my code. My test app is a simple client/server setup in a single process that sends/receive data to/on 127.0.0.1.
Best regards.
-----
visit us at
OFC 2013 / March 19-21 / Anaheim Convention Center, CA, USA / booth 11807
www.hhi.fraunhofer.de/events
^ permalink raw reply
* [PATCH iproute2 1/2] bridge: Add support for setting bridge port attributes
From: Vlad Yasevich @ 2013-03-13 20:36 UTC (permalink / raw)
To: netdev; +Cc: shemminger, john.r.fastabend
In-Reply-To: <1363206994-18599-1-git-send-email-vyasevic@redhat.com>
Add netlink support bridge port attributes such as cost, priority, state
and flags. This also adds support for HW mode such as VEPA or VEB.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
bridge/br_common.h | 1 +
bridge/bridge.c | 3 +-
bridge/link.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 221 insertions(+), 1 deletions(-)
diff --git a/bridge/br_common.h b/bridge/br_common.h
index 8764563..12fce3e 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -10,6 +10,7 @@ extern int do_fdb(int argc, char **argv);
extern int do_mdb(int argc, char **argv);
extern int do_monitor(int argc, char **argv);
extern int do_vlan(int argc, char **argv);
+extern int do_link(int argc, char **argv);
extern int preferred_family;
extern int show_stats;
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 06b7a54..77e260f 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -27,7 +27,7 @@ static void usage(void)
{
fprintf(stderr,
"Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
-"where OBJECT := { fdb | mdb | vlan | monitor }\n"
+"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" );
exit(-1);
}
@@ -42,6 +42,7 @@ static const struct cmd {
const char *cmd;
int (*func)(int argc, char **argv);
} cmds[] = {
+ { "link", do_link },
{ "fdb", do_fdb },
{ "mdb", do_mdb },
{ "vlan", do_vlan },
diff --git a/bridge/link.c b/bridge/link.c
index edb6fbf..72f2a02 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -9,10 +9,14 @@
#include <linux/if.h>
#include <linux/if_bridge.h>
#include <string.h>
+#include <stdbool.h>
+#include "libnetlink.h"
#include "utils.h"
#include "br_common.h"
+unsigned int filter_index;
+
static const char *port_states[] = {
[BR_STATE_DISABLED] = "disabled",
[BR_STATE_LISTENING] = "listening",
@@ -87,6 +91,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC))
return 0;
+ if (filter_index && filter_index != ifi->ifi_index)
+ return 0;
+
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
if (tb[IFLA_IFNAME] == NULL) {
@@ -136,3 +143,214 @@ int print_linkinfo(const struct sockaddr_nl *who,
fflush(fp);
return 0;
}
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: bridge link set dev DEV [guard {on | off}] [hairpin {on | off}] \n");
+ fprintf(stderr, " [fastleave {on | off}] [cost COST]\n");
+ fprintf(stderr, " [priority PRIO] [state STATE] [mode <vepa | veb>]\n");
+ fprintf(stderr, " [master] [self]\n");
+ fprintf(stderr, " bridge link show [dev DEV]\n");
+ exit(-1);
+}
+
+static bool on_off(char *arg, __s8 *attr, char *val)
+{
+ if (strcmp(val, "on") == 0)
+ *attr = 1;
+ else if (strcmp(val, "off") == 0)
+ *attr = 0;
+ else {
+ fprintf(stderr,
+ "Error: argument of \"%s\" must be \"on\" or \"off\"\n",
+ arg);
+ return false;
+ }
+
+ return true;
+}
+
+static int brlink_modify(int argc, char **argv)
+{
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg ifm;
+ char buf[512];
+ } req;
+ char *d = NULL;
+ __s8 hairpin = -1;
+ __s8 bpdu_guard = -1;
+ __s8 fast_leave = -1;
+ __u32 cost = 0;
+ __s16 priority = -1;
+ __s8 state = -1;
+ __s16 mode = -1;
+ __u16 flags = 0;
+ struct rtattr *nest;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = RTM_SETLINK;
+ req.ifm.ifi_family = PF_BRIDGE;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ d = *argv;
+ } else if (strcmp(*argv, "guard") == 0) {
+ NEXT_ARG();
+ if (!on_off("guard", &bpdu_guard, *argv))
+ exit(-1);
+ } else if (strcmp(*argv, "hairpin") == 0) {
+ NEXT_ARG();
+ if (!on_off("hairping", &hairpin, *argv))
+ exit(-1);
+ } else if (strcmp(*argv, "fastleave") == 0) {
+ NEXT_ARG();
+ if (!on_off("fastleave", &fast_leave, *argv))
+ exit(-1);
+ } else if (strcmp(*argv, "cost")) {
+ NEXT_ARG();
+ cost = atoi(*argv);
+ } else if (strcmp(*argv, "priority")) {
+ NEXT_ARG();
+ priority = atoi(*argv);
+ } else if (strcmp(*argv, "state")) {
+ NEXT_ARG();
+ state = atoi(*argv);
+ } else if (strcmp(*argv, "mode")) {
+ NEXT_ARG();
+ if (strcmp(*argv, "vepa") == 0)
+ mode = BRIDGE_MODE_VEPA;
+ else if (strcmp(*argv, "veb") == 0)
+ mode = BRIDGE_MODE_VEB;
+ else {
+ fprintf(stderr,
+ "Mode argument must be \"vepa\" or "
+ "\"veb\".\n");
+ exit(-1);
+ }
+ } else if (strcmp(*argv, "master")) {
+ flags |= BRIDGE_FLAGS_MASTER;
+ } else if (strcmp(*argv, "self")) {
+ flags |= BRIDGE_FLAGS_SELF;
+ } else {
+ usage();
+ }
+ argc--; argv++;
+ }
+ if (d == NULL) {
+ fprintf(stderr, "Device is a required argument.\n");
+ exit(-1);
+ }
+
+ req.ifm.ifi_index = ll_name_to_index(d);
+ if (req.ifm.ifi_index == 0) {
+ fprintf(stderr, "Cannot find bridge device \"%s\"\n", d);
+ exit(-1);
+ }
+
+ /* Nested PROTINFO attribute. Contains: port flags, cost, priority and
+ * state.
+ */
+ nest = addattr_nest(&req.n, sizeof(req),
+ IFLA_PROTINFO | NLA_F_NESTED);
+ /* Flags first */
+ if (bpdu_guard >= 0)
+ addattr8(&req.n, sizeof(req), IFLA_BRPORT_GUARD, bpdu_guard);
+ if (hairpin >= 0)
+ addattr8(&req.n, sizeof(req), IFLA_BRPORT_MODE, hairpin);
+ if (fast_leave >= 0)
+ addattr8(&req.n, sizeof(req), IFLA_BRPORT_FAST_LEAVE,
+ fast_leave);
+
+ if (cost > 0)
+ addattr32(&req.n, sizeof(req), IFLA_BRPORT_COST, cost);
+
+ if (priority >= 0)
+ addattr16(&req.n, sizeof(req), IFLA_BRPORT_PRIORITY, priority);
+
+ if (state >= 0)
+ addattr8(&req.n, sizeof(req), IFLA_BRPORT_STATE, state);
+
+ addattr_nest_end(&req.n, nest);
+
+ /* IFLA_AF_SPEC nested attribute. Contains IFLA_BRIDGE_FLAGS that
+ * designates master or self operation as well as 'vepa' or 'veb'
+ * operation modes. These are only valid in 'self' mode on some
+ * devices so far.
+ */
+ if (flags || mode >= 0) {
+ nest = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
+
+ if (flags)
+ addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS,
+ flags);
+
+ if (mode >= 0)
+ addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode);
+
+ addattr_nest_end(&req.n, nest);
+ }
+
+ if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
+ exit(2);
+
+ return 0;
+}
+
+static int brlink_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 = ll_name_to_index(filter_dev)) == 0) {
+ fprintf(stderr, "Cannot find device \"%s\"\n",
+ filter_dev);
+ return -1;
+ }
+ }
+
+ if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
+ perror("Cannon send dump request");
+ exit(1);
+ }
+
+ if (rtnl_dump_filter(&rth, print_linkinfo, stdout) < 0) {
+ fprintf(stderr, "Dump terminated\n");
+ exit(1);
+ }
+ return 0;
+}
+
+int do_link(int argc, char **argv)
+{
+ ll_init_map(&rth);
+ if (argc > 0) {
+ if (matches(*argv, "set") == 0 ||
+ matches(*argv, "change") == 0)
+ return brlink_modify(argc-1, argv+1);
+ if (matches(*argv, "show") == 0 ||
+ matches(*argv, "lst") == 0 ||
+ matches(*argv, "list") == 0)
+ return brlink_show(argc-1, argv+1);
+ if (matches(*argv, "help") == 0)
+ usage();
+ } else
+ return brlink_show(0, NULL);
+
+ fprintf(stderr, "Command \"%s\" is unknown, try \"bridge link help\".\n", *argv);
+ exit(-1);
+}
--
1.7.7.6
^ permalink raw reply related
* [PATCH iproute2 2/2] bridge: Add support for printing bridge port attributes
From: Vlad Yasevich @ 2013-03-13 20:36 UTC (permalink / raw)
To: netdev; +Cc: shemminger, john.r.fastabend
In-Reply-To: <1363206994-18599-1-git-send-email-vyasevic@redhat.com>
Output new nested bridge port attributes.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
bridge/link.c | 71 +++++++++++++++++++++++++++++++++++++++++++++----
include/libnetlink.h | 2 +
lib/libnetlink.c | 13 ++++++++-
3 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/bridge/link.c b/bridge/link.c
index 72f2a02..48b98f2 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -65,6 +65,8 @@ static const char *oper_states[] = {
"TESTING", "DORMANT", "UP"
};
+static const char *hw_mode[] = {"VEB", "VEPA"};
+
static void print_operstate(FILE *f, __u8 state)
{
if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
@@ -73,6 +75,28 @@ static void print_operstate(FILE *f, __u8 state)
fprintf(f, "state %s ", oper_states[state]);
}
+static void print_portstate(FILE *f, __u8 state)
+{
+ if (state <= BR_STATE_BLOCKING)
+ fprintf(f, "state %s ", port_states[state]);
+ else
+ fprintf(f, "state (%d) ", state);
+}
+
+static void print_portflag(FILE *f, char *flag, __u8 val)
+{
+ if (val)
+ fprintf(f, "%s ", flag);
+}
+
+static void print_hwmode(FILE *f, __u16 mode)
+{
+ if (mode >= sizeof(hw_mode)/sizeof(hw_mode[0]))
+ fprintf(f, "HW mode %#hx ", mode);
+ else
+ fprintf(f, "HW mode %s ", hw_mode[mode]);
+}
+
int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{
@@ -94,7 +118,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (filter_index && filter_index != ifi->ifi_index)
return 0;
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+ parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
if (tb[IFLA_IFNAME] == NULL) {
fprintf(stderr, "BUG: nil ifname\n");
@@ -131,13 +155,48 @@ int print_linkinfo(const struct sockaddr_nl *who,
if_indextoname(rta_getattr_u32(tb[IFLA_MASTER]), b1));
if (tb[IFLA_PROTINFO]) {
- __u8 state = rta_getattr_u8(tb[IFLA_PROTINFO]);
- if (state <= BR_STATE_BLOCKING)
- fprintf(fp, "state %s", port_states[state]);
- else
- fprintf(fp, "state (%d)", state);
+ if (tb[IFLA_PROTINFO]->rta_type & NLA_F_NESTED) {
+ struct rtattr *prtb[IFLA_BRPORT_MAX+1];
+
+ parse_rtattr_nested(prtb, IFLA_BRPORT_MAX,
+ tb[IFLA_PROTINFO]);
+
+ if (prtb[IFLA_BRPORT_STATE])
+ print_portstate(fp,
+ rta_getattr_u8(prtb[IFLA_BRPORT_STATE]));
+ if (prtb[IFLA_BRPORT_PRIORITY])
+ fprintf(fp, "priority %hu ",
+ rta_getattr_u16(prtb[IFLA_BRPORT_PRIORITY]));
+ if (prtb[IFLA_BRPORT_COST])
+ fprintf(fp, "cost %u ",
+ rta_getattr_u32(prtb[IFLA_BRPORT_COST]));
+ if (prtb[IFLA_BRPORT_MODE])
+ print_portflag(fp, "hairpin mode",
+ rta_getattr_u8(prtb[IFLA_BRPORT_MODE]));
+ if (prtb[IFLA_BRPORT_GUARD])
+ print_portflag(fp, "bpdu guard",
+ rta_getattr_u8(prtb[IFLA_BRPORT_GUARD]));
+ if (prtb[IFLA_BRPORT_PROTECT])
+ print_portflag(fp, "root block",
+ rta_getattr_u8(prtb[IFLA_BRPORT_PROTECT]));
+ if (prtb[IFLA_BRPORT_FAST_LEAVE])
+ print_portflag(fp, "multicast fast leave",
+ rta_getattr_u8(prtb[IFLA_BRPORT_FAST_LEAVE]));
+ } else
+ print_portstate(fp, rta_getattr_u8(tb[IFLA_PROTINFO]));
}
+ if (tb[IFLA_AF_SPEC]) {
+ /* This is reported by HW devices that have some bridging
+ * capabilities.
+ */
+ struct rtattr *aftb[IFLA_BRIDGE_MAX+1];
+
+ parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]);
+
+ if (tb[IFLA_BRIDGE_MODE])
+ print_hwmode(fp, rta_getattr_u16(tb[IFLA_BRIDGE_MODE]));
+ }
fprintf(fp, "\n");
fflush(fp);
diff --git a/include/libnetlink.h b/include/libnetlink.h
index 8d15ee5..ec3d657 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -65,6 +65,8 @@ extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen);
extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
+extern int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+ int len, unsigned short flags);
extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 67f046f..f262959 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -658,10 +658,19 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
+ return parse_rtattr_flags(tb, max, rta, len, 0);
+}
+
+int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+ int len, unsigned short flags)
+{
+ unsigned short type;
+
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
while (RTA_OK(rta, len)) {
- if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
- tb[rta->rta_type] = rta;
+ type = rta->rta_type & ~flags;
+ if ((type <= max) && (!tb[type]))
+ tb[type] = rta;
rta = RTA_NEXT(rta,len);
}
if (len)
--
1.7.7.6
^ permalink raw reply related
* [PATCH iproute2 0/2] Add support for bridge port link information
From: Vlad Yasevich @ 2013-03-13 20:36 UTC (permalink / raw)
To: netdev; +Cc: shemminger, john.r.fastabend
Bridge ports provide unique link information about the properties and flags of
the port. This patch set allows bridge utility to configure and disaplay
this information.
Vlad Yasevich (2):
bridge: Add support for setting bridge port attributes
bridge: Add support for printing bridge port attributes
bridge/br_common.h | 1 +
bridge/bridge.c | 3 +-
bridge/link.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/libnetlink.h | 2 +
lib/libnetlink.c | 13 ++-
5 files changed, 299 insertions(+), 9 deletions(-)
--
1.7.7.6
^ permalink raw reply
* Re: [PATCH net-next 2/4] bridge: Allow an ability to designate an uplink port
From: Michael S. Tsirkin @ 2013-03-13 20:33 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, bridge
In-Reply-To: <1363139126-13396-3-git-send-email-vyasevic@redhat.com>
On Tue, Mar 12, 2013 at 09:45:24PM -0400, Vlad Yasevich wrote:
> Allow a ports to be designated as uplink. Multiple ports
> may be designated as uplinks and they will be kept in a
> list.
>
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
It looks like if you make two links uplink, bridging
between them won't work at all?
> ---
> include/uapi/linux/if_link.h | 1 +
> net/bridge/br_netlink.c | 2 ++
> net/bridge/br_private.h | 1 +
> net/bridge/br_sysfs_if.c | 2 ++
> 4 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index c4edfe1..b9444e9 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -220,6 +220,7 @@ enum {
> IFLA_BRPORT_GUARD, /* bpdu guard */
> IFLA_BRPORT_PROTECT, /* root port protection */
> IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
> + IFLA_BRPORT_UPLINK, /* uplink port */
> __IFLA_BRPORT_MAX
> };
> #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index 27aa3ee..e08a50e 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -283,6 +283,7 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
> [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
> [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
> [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
> + [IFLA_BRPORT_UPLINK] = { .type = NLA_U8 },
> };
>
> /* Change the state of the port and notify spanning tree */
> @@ -329,6 +330,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
> br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
> br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
> br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
> + br_set_port_flag(p, tb, IFLA_BRPORT_UPLINK, BR_UPLINK);
>
> if (tb[IFLA_BRPORT_COST]) {
> err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 4a0fa29..44ae584 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -156,6 +156,7 @@ struct net_bridge_port
> #define BR_BPDU_GUARD 0x00000002
> #define BR_ROOT_BLOCK 0x00000004
> #define BR_MULTICAST_FAST_LEAVE 0x00000008
> +#define BR_UPLINK 0x00000010
>
> #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> u32 multicast_startup_queries_sent;
> diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> index a1ef1b6..1f28cd4 100644
> --- a/net/bridge/br_sysfs_if.c
> +++ b/net/bridge/br_sysfs_if.c
> @@ -158,6 +158,7 @@ static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush);
> BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE);
> BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD);
> BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK);
> +BRPORT_ATTR_FLAG(uplink, BR_UPLINK);
>
> #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
> @@ -195,6 +196,7 @@ static const struct brport_attribute *brport_attrs[] = {
> &brport_attr_hairpin_mode,
> &brport_attr_bpdu_guard,
> &brport_attr_root_block,
> + &brport_attr_uplink,
> #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> &brport_attr_multicast_router,
> &brport_attr_multicast_fast_leave,
> --
> 1.7.7.6
>
> --
> 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 net-next 0/4] Allow bridge to function in non-promisc mode
From: Michael S. Tsirkin @ 2013-03-13 20:31 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, bridge
In-Reply-To: <1363139126-13396-1-git-send-email-vyasevic@redhat.com>
On Tue, Mar 12, 2013 at 09:45:22PM -0400, Vlad Yasevich wrote:
> The series adds an ability for the bridge to function in non-promiscuous mode.
> We do it in 3 steps.
> First we add an interface to palce the switch into non-promisc mode. In
> this mode, all port of the switch turn promisc off and turn on IFF_ALLMULTI
> to continue handling multicast traffic.
Hmm why not go the extra mile and do same thing for multicast?
> Second we add an ability to designate a bridge port as uplink.
> Third we add IFF_UNICAST_FLT support to the bridge and sync all unicast
> HW addresses to the uplink ports.
> Default bridge operation continues to remain "promiscuous". The new
> functionality has to be enabled via sysfs (similar to other bridge extensions).
>
> The uplink mode is implemented as a flag on a bridge port. The api to
> change that flag follows the existing api to enable/disable other existing
> flags.
Actually, it seems a bit tricky to use correctly. Specifying MACs is
straight-forward enough, but as you add and remove interfaces, you would
need to play with uplink and promisc bits. I also think that for setups
you describe, where we really want to forward traffic to VMs and that's
all, promisc mode is an implementation detail. If true it's a mistake to
expose it in an interface. Here's an idea how we could make it work
automatically:
- Like your patch does, allow two kinds of ports: port that only wants
specific addresses and "wildcard" port that can get all addresses
All ports default to wildcard as a compatible way
- For port A, if there is some wildcard port besides A, A must be
promiscous since maybe it needs to get packets that will be later
forwardd to A
- For port A, if there are no wildcard ports, or if A is the only
wildcard, A does not need to be promiscous.
Instead we can program it with addresses of all other ports.
Exactly same logic applies, separately, for unicast, where promisc
means all uni, and multicast, where promisc means all multi.
Now there's no special unplink port, no need to enable/disable special
mode, nothing: just program addresses for ports and go.
> Changes since rfc v2:
> * Sync/unsync address on uplink upon the uplink flag change. This allows
> for uplink replacements without loss of addresses.
>
> Changes since rfc v1:
> * Fixed submit log
> * Simplifyied uplink logic. Uplink is now a flag per port. This removes the
> need for a separate list.
> * Clean-up hw list once the port has been removed.
>
> Vlad Yasevich (4):
> bridge: Add sysfs interface to control promisc mode
> bridge: Allow an ability to designate an uplink port
> bridge: Implement IFF_UNICAST_FLT
> bridge: sync device list when a new uplink is designated
>
> include/uapi/linux/if_link.h | 1 +
> net/bridge/br_device.c | 52 +++++++++++++++++++++++++++++++++++++++++-
> net/bridge/br_fdb.c | 6 +++++
> net/bridge/br_if.c | 24 +++++++++++++++----
> net/bridge/br_netlink.c | 13 ++++++++++
> net/bridge/br_private.h | 3 ++
> net/bridge/br_sysfs_br.c | 17 +++++++++++++
> net/bridge/br_sysfs_if.c | 27 +++++++++++++++++++++
> 8 files changed, 137 insertions(+), 6 deletions(-)
>
> --
> 1.7.7.6
>
> --
> 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
* Hello,
From: Mr.Lan Lee @ 2013-03-13 20:15 UTC (permalink / raw)
Hello,
I have information for you about an unclaimed funds in my department.
Please get back to me if interested so I would brief you in details.
Email: mr.lan_lee@fengv.com
Regards,
Mr.Lan Lee
^ permalink raw reply
* Re: [PATCH net-next 0/4] Allow bridge to function in non-promisc mode
From: Michael S. Tsirkin @ 2013-03-13 20:08 UTC (permalink / raw)
To: Vlad Yasevich
Cc: Stephen Hemminger, Oleg A. Arkhangelsky, netdev@vger.kernel.org,
bridge@lists.linux-foundation.org
In-Reply-To: <5140B1B3.2070205@redhat.com>
On Wed, Mar 13, 2013 at 01:04:51PM -0400, Vlad Yasevich wrote:
> On 03/13/2013 12:09 PM, Stephen Hemminger wrote:
> >On Wed, 13 Mar 2013 11:45:40 -0400
> >Vlad Yasevich <vyasevic@redhat.com> wrote:
> >
> >>On 03/13/2013 11:39 AM, Stephen Hemminger wrote:
> >>>On Wed, 13 Mar 2013 08:12:29 -0400
> >>>Vlad Yasevich <vyasevic@redhat.com> wrote:
> >>>
> >>>>On 03/13/2013 02:22 AM, "Oleg A. Arkhangelsky" wrote:
> >>>>>
> >>>>>
> >>>>>13.03.2013, 05:45, "Vlad Yasevich" <vyasevic@redhat.com>:
> >>>>>
> >>>>>>The series adds an ability for the bridge to function in non-promiscuous mode.
> >>>>>
> >>>>>What is the practical applications for such setup? In other words,
> >>>>>in which cases I would want to put bridge into non-promiscuous
> >>>>>mode and specify some uplink ports?
> >>>>>
> >>>>
> >>>>On of the applications would be when bridge is an edge device servicing
> >>>>a VM deployment. Each of the VMs knows the mac address that the guest
> >>>>has and may program that mac onto the uplinks.
> >>>
> >>>Why wouldn't that environment just use macvlan?
> >>>Is it because changing libvirt is harder than changing the kernel?
> >>>
> >>
> >>No, because macvlan has a drawback that it doesn't easily let guests
> >>talk to the host. Bridge is still most commonly used for just that reason.
> >>
> >>-vlad
> >
> >Maybe fixing that with a flag to macvlan would be easier?
> >
>
> Not really. macvlan to physical device could be made simple enough.
> However, physical to macvlan is non-trivial at all.
>
> We get around this right now by crating a macvlan on the host and
> have macvlan to macvlan communication essentially turning it into
> bridge. But that doesn't work in all scenarios either.
>
> -vlad
Yea macvlan bridged mode is a strange beast. It almost wants to be a
bridge, but does not dare, for example it punts on all the issues we
have fixed in the bridge like multicast snooping, and just floods
packets.
Another issue is that different VMs have different needs. You might want
to run VMs that simply use a single MAC, so no need for promisc mode,
then want to start another VM that does bridging so we need to enable
promisc mode dynamically. I guess we could switch from macvtap to
tap and back, but it's pretty nasty.
> --
> 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] ssb: pci: Fix flipping of MAC address
From: Larry Finger @ 2013-03-13 19:14 UTC (permalink / raw)
To: John W. Linville
Cc: b43-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
zajec5-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <20130313181817.GB19917-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
On 03/13/2013 01:18 PM, John W. Linville wrote:
> On Mon, Mar 11, 2013 at 03:38:26PM -0500, Larry Finger wrote:
>> Since commit e565275 entitled "ssb: pci: Standardize a function to get mac
>> address", the SPROM readout of the MAC has had the values flipped so that
>> 00:11:22:33:44:55 became 11:00:33:22:55:44. The fix has been tested on both
>> little- and big-endian architectures.
>>
>> Reported-by: Rafał Miłecki <zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
>> ---
>>
>> John,
>>
>> This bug was introduced in 3.9, and should be fixed there.
>>
>> Thanks,
>>
>> Larry
>> ---
>>
>> Index: wireless-testing-new/drivers/ssb/pci.c
>> ===================================================================
>> --- wireless-testing-new.orig/drivers/ssb/pci.c
>> +++ wireless-testing-new/drivers/ssb/pci.c
>> @@ -234,8 +234,8 @@ static void sprom_get_mac(char *mac, con
>> {
>> int i;
>> for (i = 0; i < 3; i++) {
>> - *mac++ = in[i];
>> *mac++ = in[i] >> 8;
>> + *mac++ = in[i];
>> }
>> }
>
> Actually, FWIW it seems to have been introduced in commit
> e5652756ff36ed9e1283121f788e6a17117efcab, which is slated for 3.10.
> I'm happy to merge it in wireless-next.
After further checking, I agree that it is not in 3.9. As long as the fix is
merged before 3.10, all will be OK.
Sorry for the confusion.
Larry
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [Bridge] [PATCH net-next 0/4] Allow bridge to function in non-promisc mode
From: Joel Wirāmu Pauling @ 2013-03-13 18:56 UTC (permalink / raw)
To: vyasevic
Cc: Stephen Hemminger, netdev@vger.kernel.org,
bridge@lists.linux-foundation.org, Oleg A. Arkhangelsky
In-Reply-To: <5140B1B3.2070205@redhat.com>
I agree that this is a useful behavior, often we will use a bridge in
the same scenario (multiple virtio tap adapters belonging to VM's)
another scenario is when creating a bridge for chaining multiple VPN's
together.
-Joel
On 14 March 2013 06:04, Vlad Yasevich <vyasevic@redhat.com> wrote:
> On 03/13/2013 12:09 PM, Stephen Hemminger wrote:
>>
>> On Wed, 13 Mar 2013 11:45:40 -0400
>> Vlad Yasevich <vyasevic@redhat.com> wrote:
>>
>>> On 03/13/2013 11:39 AM, Stephen Hemminger wrote:
>>>>
>>>> On Wed, 13 Mar 2013 08:12:29 -0400
>>>> Vlad Yasevich <vyasevic@redhat.com> wrote:
>>>>
>>>>> On 03/13/2013 02:22 AM, "Oleg A. Arkhangelsky" wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> 13.03.2013, 05:45, "Vlad Yasevich" <vyasevic@redhat.com>:
>>>>>>
>>>>>>> The series adds an ability for the bridge to function in
>>>>>>> non-promiscuous mode.
>>>>>>
>>>>>>
>>>>>> What is the practical applications for such setup? In other words,
>>>>>> in which cases I would want to put bridge into non-promiscuous
>>>>>> mode and specify some uplink ports?
>>>>>>
>>>>>
>>>>> On of the applications would be when bridge is an edge device servicing
>>>>> a VM deployment. Each of the VMs knows the mac address that the guest
>>>>> has and may program that mac onto the uplinks.
>>>>
>>>>
>>>> Why wouldn't that environment just use macvlan?
>>>> Is it because changing libvirt is harder than changing the kernel?
>>>>
>>>
>>> No, because macvlan has a drawback that it doesn't easily let guests
>>> talk to the host. Bridge is still most commonly used for just that
>>> reason.
>>>
>>> -vlad
>>
>>
>> Maybe fixing that with a flag to macvlan would be easier?
>>
>
> Not really. macvlan to physical device could be made simple enough.
> However, physical to macvlan is non-trivial at all.
>
> We get around this right now by crating a macvlan on the host and
> have macvlan to macvlan communication essentially turning it into
> bridge. But that doesn't work in all scenarios either.
>
> -vlad
^ permalink raw reply
* [PATCH v3.4-stable] myri10ge: Restrict LRO max_aggr based on MTU
From: Andrew Gallatin @ 2013-03-13 18:46 UTC (permalink / raw)
To: davem, gregkh; +Cc: stable, netdev, Andrew Gallatin
Fix a longstanding panic when myri10ge would configure
lro_mgr->max_aggr wrong, so that lro could aggregate more than
MAX_SKB_FRAGS frags when jumbo frames (which consume multiple frags)
are used.
To fix this, we determine the frags per packet in excess of MAX_SKB_FRAGS
for the current MTU, and subtract those extra frags from MAX_SKB_FRAGS
when configuring lro_mgr->max_aggr to ensure that MAX_SKB_FRAGS will not
be exceeded.
This does not apply to the mainline, because LRO was removed from
myri10ge when it was converted to use GRO in 4ca3221 (appeared in 3.8).
It should probably be merged to all active stable kernels prior to
3.8, since it fixes a panic.
Signed-off-by: Andrew Gallatin <gallatin@myri.com>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 27273ae..99fa774 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -2406,7 +2406,7 @@ static int myri10ge_open(struct net_device *dev)
struct myri10ge_slice_state *ss;
struct myri10ge_priv *mgp = netdev_priv(dev);
struct myri10ge_cmd cmd;
- int i, status, big_pow2, slice;
+ int i, status, big_pow2, slice, extra_frags;
u8 *itable;
struct net_lro_mgr *lro_mgr;
@@ -2529,8 +2529,10 @@ static int myri10ge_open(struct net_device *dev)
lro_mgr->get_frag_header = myri10ge_get_frag_header;
lro_mgr->max_aggr = myri10ge_lro_max_pkts;
lro_mgr->frag_align_pad = 2;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
+ extra_frags = (dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD) /
+ MYRI10GE_ALLOC_SIZE;
+ if (lro_mgr->max_aggr > MAX_SKB_FRAGS - extra_frags)
+ lro_mgr->max_aggr = MAX_SKB_FRAGS - extra_frags;
/* must happen prior to any irq */
napi_enable(&(ss)->napi);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] ssb: pci: Fix flipping of MAC address
From: John W. Linville @ 2013-03-13 18:18 UTC (permalink / raw)
To: Larry Finger; +Cc: b43-dev, netdev, linux-wireless, zajec5
In-Reply-To: <513e40c2.MDaC+Q82iTl9PpIZ%Larry.Finger@lwfinger.net>
On Mon, Mar 11, 2013 at 03:38:26PM -0500, Larry Finger wrote:
> Since commit e565275 entitled "ssb: pci: Standardize a function to get mac
> address", the SPROM readout of the MAC has had the values flipped so that
> 00:11:22:33:44:55 became 11:00:33:22:55:44. The fix has been tested on both
> little- and big-endian architectures.
>
> Reported-by: Rafał Miłecki <zajec5@gmail.com>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
>
> John,
>
> This bug was introduced in 3.9, and should be fixed there.
>
> Thanks,
>
> Larry
> ---
>
> Index: wireless-testing-new/drivers/ssb/pci.c
> ===================================================================
> --- wireless-testing-new.orig/drivers/ssb/pci.c
> +++ wireless-testing-new/drivers/ssb/pci.c
> @@ -234,8 +234,8 @@ static void sprom_get_mac(char *mac, con
> {
> int i;
> for (i = 0; i < 3; i++) {
> - *mac++ = in[i];
> *mac++ = in[i] >> 8;
> + *mac++ = in[i];
> }
> }
Actually, FWIW it seems to have been introduced in commit
e5652756ff36ed9e1283121f788e6a17117efcab, which is slated for 3.10.
I'm happy to merge it in wireless-next.
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: question about creating patch
From: Ben Hutchings @ 2013-03-13 17:16 UTC (permalink / raw)
To: Zhouyi Zhou; +Cc: netdev
In-Reply-To: <CAABZP2zDU9UGRARWFBP86W28=pKa2T2mo1E8CaLAaRAu7yNSuQ@mail.gmail.com>
On Thu, 2013-03-14 at 00:11 +0800, Zhouyi Zhou wrote:
> Dear Colleagues,
> I have read Kushal Koolwal's article
> "HOWTO: Create and submit your first Linux kernel patch using GIT"
> and one question remain
> which tree is preferable in git://git.kernel.org/pub/scm/ should I
> clone in git clone step,
> linux/kernel/git/stable/linux-stable.git
> or
> linux/kernel/git/davem/net.git
> Many thanks
There is an easy way to answer your question for most areas of the
kernel, which is to look for a 'T:' line in the MAINTAINERS section.
For networking you will see:
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
The first of these is for changes that should go into the pending
release (at present that would be 3.9), limited to important bug fixes
and (sometimes) new drivers. The second is for new features and more
minor bug fixes that can wait for the next release.
Ben.
--
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
* Re: [PATCH net-next 0/4] Allow bridge to function in non-promisc mode
From: Vlad Yasevich @ 2013-03-13 17:04 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Oleg A. Arkhangelsky, netdev@vger.kernel.org,
bridge@lists.linux-foundation.org
In-Reply-To: <20130313090921.05dbf6e2@nehalam.linuxnetplumber.net>
On 03/13/2013 12:09 PM, Stephen Hemminger wrote:
> On Wed, 13 Mar 2013 11:45:40 -0400
> Vlad Yasevich <vyasevic@redhat.com> wrote:
>
>> On 03/13/2013 11:39 AM, Stephen Hemminger wrote:
>>> On Wed, 13 Mar 2013 08:12:29 -0400
>>> Vlad Yasevich <vyasevic@redhat.com> wrote:
>>>
>>>> On 03/13/2013 02:22 AM, "Oleg A. Arkhangelsky" wrote:
>>>>>
>>>>>
>>>>> 13.03.2013, 05:45, "Vlad Yasevich" <vyasevic@redhat.com>:
>>>>>
>>>>>> The series adds an ability for the bridge to function in non-promiscuous mode.
>>>>>
>>>>> What is the practical applications for such setup? In other words,
>>>>> in which cases I would want to put bridge into non-promiscuous
>>>>> mode and specify some uplink ports?
>>>>>
>>>>
>>>> On of the applications would be when bridge is an edge device servicing
>>>> a VM deployment. Each of the VMs knows the mac address that the guest
>>>> has and may program that mac onto the uplinks.
>>>
>>> Why wouldn't that environment just use macvlan?
>>> Is it because changing libvirt is harder than changing the kernel?
>>>
>>
>> No, because macvlan has a drawback that it doesn't easily let guests
>> talk to the host. Bridge is still most commonly used for just that reason.
>>
>> -vlad
>
> Maybe fixing that with a flag to macvlan would be easier?
>
Not really. macvlan to physical device could be made simple enough.
However, physical to macvlan is non-trivial at all.
We get around this right now by crating a macvlan on the host and
have macvlan to macvlan communication essentially turning it into
bridge. But that doesn't work in all scenarios either.
-vlad
^ permalink raw reply
* Re: [PATCH] Rate should be u64 to avoid integer overflow at high speeds (>= ~35Gbit)
From: Chris Friesen @ 2013-03-13 16:57 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Bill Fink, Eric Dumazet, Thomas Graf, Vimal, netdev, shemminger
In-Reply-To: <20130313083400.2329e982@nehalam.linuxnetplumber.net>
On 03/13/2013 09:34 AM, Stephen Hemminger wrote:
> As others have said the multiplier shift approach is a not a workable
> solution because it is likely to cause too many compatibility surprises.
> Older kernels would ignore the multiplier and therefore not give the users
> the effective rate they wanted.
How is that any different than ignoring the 64-bit value and not giving
the effective rate they wanted?
Chris
^ permalink raw reply
* Re: [RFC] net: cdc_ncm, cdc_mbim: allow user to prefer NCM for backwards compatibility
From: Bjørn Mork @ 2013-03-13 16:55 UTC (permalink / raw)
To: Greg Suarez; +Cc: Alexey Orishko, linux-usb, netdev
In-Reply-To: <1362939209-19056-1-git-send-email-bjorn@mork.no>
Bjørn Mork <bjorn@mork.no> writes:
> +#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
> +static bool prefer_mbim = true;
> +#else
> +static bool prefer_mbim;
> +#endif
> +module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
> +MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM on NCM/MBIM backwards compatible functions");
So, noone wanting to comment on this? I am not sure how to interpret
that. If I liked the solution myself I would just have taken it as an
unanimous ack, but I don't...
Please, if your gut feeling is that this is the most stupid thing you've
ever seen, then just say so. I can take it :)
Bjørn
^ permalink raw reply
* Re: [PATCH] sctp: optimize searching the active path for tsns
From: Paul E. McKenney @ 2013-03-13 16:41 UTC (permalink / raw)
To: Neil Horman; +Cc: Vlad Yasevich, linux-sctp, Xufeng Zhang, davem, netdev
In-Reply-To: <20130313132809.GA17592@hmsreliant.think-freely.org>
On Wed, Mar 13, 2013 at 09:28:09AM -0400, Neil Horman wrote:
> On Tue, Mar 12, 2013 at 09:43:20PM -0400, Vlad Yasevich wrote:
> > On 03/12/2013 09:20 PM, Neil Horman wrote:
> > >On Tue, Mar 12, 2013 at 05:01:50PM -0400, Vlad Yasevich wrote:
> > >>Hi Neil
> > >>
> > >>On 03/12/2013 01:29 PM, Neil Horman wrote:
> > >>>SCTP currently attempts to optimize the search for tsns on a transport by first
> > >>>checking the active_path, then searching alternate transports. This operation
> > >>>however is a bit convoluted, as we explicitly search the active path, then serch
> > >>>all other transports, skipping the active path, when its detected. Lets
> > >>>optimize this by preforming a move to front on the transport_addr_list every
> > >>>time the active_path is changed. The active_path changes occur in relatively
> > >>>non-critical paths, and doing so allows us to just search the
> > >>>transport_addr_list in order, avoiding an extra conditional check in the
> > >>>relatively hot tsn lookup path. This also happens to fix a bug where we break
> > >>>out of the for loop early in the tsn lookup.
> > >>>
> > >>>CC: Xufeng Zhang <xufengzhang.main@gmail.com>
> > >>>CC: vyasevich@gmail.com
> > >>>CC: davem@davemloft.net
> > >>>CC: netdev@vger.kernel.org
> > >>>---
> > >>> net/sctp/associola.c | 31 ++++++++++++-------------------
> > >>> 1 file changed, 12 insertions(+), 19 deletions(-)
> > >>>
> > >>>diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> > >>>index 43cd0dd..7af96b3 100644
> > >>>--- a/net/sctp/associola.c
> > >>>+++ b/net/sctp/associola.c
> > >>>@@ -513,8 +513,11 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
> > >>> * user wants to use this new path.
> > >>> */
> > >>> if ((transport->state == SCTP_ACTIVE) ||
> > >>>- (transport->state == SCTP_UNKNOWN))
> > >>>+ (transport->state == SCTP_UNKNOWN)) {
> > >>>+ list_del_rcu(&transport->transports);
> > >>>+ list_add_rcu(&transport->transports, &asoc->peer.transport_addr_list);
> > >>> asoc->peer.active_path = transport;
> > >>>+ }
> > >>
> > >>What would happen if at the same time someone is walking the list
> > >>through the proc interfaces?
> > >>
> > >>Since you are effectively changing the .next pointer, I think it is
> > >>possible to get a duplicate transport output essentially corrupting
> > >>the output.
> > >>
> > >It would be the case, but you're using the rcu variants of the list_add macros
> > >at all the points where we modify the list (some of which we do at call sites
> > >right before we call set_primary, see sctp_assoc_add_peer, where
> > >list_add_tail_rcu also modifies a next pointer). So if this is a problem, its a
> > >problem without this patch. In fact looking at it, our list access to
> > >transport_addr_list is broken, as we use rcu apis to modify the list but non-rcu
> > >apis to traverse the list. I'll need to fix that first.
> >
> > As long as we are under lock, we don't need rcu variants for
> > traversal. The traversals done by the sctp_seq_ functions already
> > use correct rcu variants.
> >
> > I don't see this as a problem right now since we either delete the
> > transport, or add it. We don't move it to a new location in the list.
> > With the move, what could happen is that while sctp_seq_ is printing
> > a transport, you might move it to another spot, and the when you grab
> > the .next pointer on the next iteration, it points to a completely
> > different spot.
> >
> Ok, I see what you're saying, and looking at the seq code, with your description
> I see how we're using half the rcu code to allow the proc interface to avoid
> grabbing the socket lock. But this just strikes me a poor coding. Its
> confusing to say the least, and begging for mistakes like the one I just made to
> be made again. Regardless of necessisty, it seems to me the code would be both
> more readable and understandible if we modified it so that we used the rcu api
> consistently to access that list.
Not sure exactly what the desired behavior is, but if the idea is to be
able to move an element within an RCU-protected list without dragging
RCU readers along (and thus having the readers possibly traverse parts
of the list multiple times), here are some ways of accomplishing this:
o Insert a synchronize_rcu() between the removal and the
reinsertion (which means upgrading any spinlocks to mutexes
or some such).
o Instead of moving the object, insert a copy after removing
the old version. Any readers referencing the old copy would
continue down the list. A reader traversing the list between
the removal of the original and the insertion of the copy might
miss the moving element.
You could instead insert the copy before removing the original,
so that both copies are in the list for a bit, in which case a
concurrent reader might see both.
o If it is OK to miss elements but bad to repeat them, instead
of moving the selected element to the beginning of the list,
move all items preceding that element to the end of the list.
o Have a pair of list_heads in each object, along with an index
telling which of them pair readers should use. Make the change
using the non-current set of list_heads. Flip the index.
Wait for a grace period before allowing the next update.
On the off-chance that any of this is helpful... There are probably
other ways of making this work as well.
Thanx, Paul
^ permalink raw reply
* Re: [PATCH] sctp: optimize searching the active path for tsns
From: Vlad Yasevich @ 2013-03-13 16:40 UTC (permalink / raw)
To: Neil Horman
Cc: Vlad Yasevich, linux-sctp@vger.kernel.org, Xufeng Zhang, davem,
netdev
In-Reply-To: <20130313142104.GE17592@hmsreliant.think-freely.org>
On 03/13/2013 10:21 AM, Neil Horman wrote:
> On Wed, Mar 13, 2013 at 10:06:43AM -0400, Vlad Yasevich wrote:
>> On 03/13/2013 09:28 AM, Neil Horman wrote:
>>> On Tue, Mar 12, 2013 at 09:43:20PM -0400, Vlad Yasevich wrote:
>>>> On 03/12/2013 09:20 PM, Neil Horman wrote:
>>>>> On Tue, Mar 12, 2013 at 05:01:50PM -0400, Vlad Yasevich wrote:
>>>>>> Hi Neil
>>>>>>
>>>>>> On 03/12/2013 01:29 PM, Neil Horman wrote:
>>>>>>> SCTP currently attempts to optimize the search for tsns on a transport by first
>>>>>>> checking the active_path, then searching alternate transports. This operation
>>>>>>> however is a bit convoluted, as we explicitly search the active path, then serch
>>>>>>> all other transports, skipping the active path, when its detected. Lets
>>>>>>> optimize this by preforming a move to front on the transport_addr_list every
>>>>>>> time the active_path is changed. The active_path changes occur in relatively
>>>>>>> non-critical paths, and doing so allows us to just search the
>>>>>>> transport_addr_list in order, avoiding an extra conditional check in the
>>>>>>> relatively hot tsn lookup path. This also happens to fix a bug where we break
>>>>>>> out of the for loop early in the tsn lookup.
>>>>>>>
>>>>>>> CC: Xufeng Zhang <xufengzhang.main@gmail.com>
>>>>>>> CC: vyasevich@gmail.com
>>>>>>> CC: davem@davemloft.net
>>>>>>> CC: netdev@vger.kernel.org
>>>>>>> ---
>>>>>>> net/sctp/associola.c | 31 ++++++++++++-------------------
>>>>>>> 1 file changed, 12 insertions(+), 19 deletions(-)
>>>>>>>
>>>>>>> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
>>>>>>> index 43cd0dd..7af96b3 100644
>>>>>>> --- a/net/sctp/associola.c
>>>>>>> +++ b/net/sctp/associola.c
>>>>>>> @@ -513,8 +513,11 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
>>>>>>> * user wants to use this new path.
>>>>>>> */
>>>>>>> if ((transport->state == SCTP_ACTIVE) ||
>>>>>>> - (transport->state == SCTP_UNKNOWN))
>>>>>>> + (transport->state == SCTP_UNKNOWN)) {
>>>>>>> + list_del_rcu(&transport->transports);
>>>>>>> + list_add_rcu(&transport->transports, &asoc->peer.transport_addr_list);
>>>>>>> asoc->peer.active_path = transport;
>>>>>>> + }
>>>>>>
>>>>>> What would happen if at the same time someone is walking the list
>>>>>> through the proc interfaces?
>>>>>>
>>>>>> Since you are effectively changing the .next pointer, I think it is
>>>>>> possible to get a duplicate transport output essentially corrupting
>>>>>> the output.
>>>>>>
>>>>> It would be the case, but you're using the rcu variants of the list_add macros
>>>>> at all the points where we modify the list (some of which we do at call sites
>>>>> right before we call set_primary, see sctp_assoc_add_peer, where
>>>>> list_add_tail_rcu also modifies a next pointer). So if this is a problem, its a
>>>>> problem without this patch. In fact looking at it, our list access to
>>>>> transport_addr_list is broken, as we use rcu apis to modify the list but non-rcu
>>>>> apis to traverse the list. I'll need to fix that first.
>>>>
>>>> As long as we are under lock, we don't need rcu variants for
>>>> traversal. The traversals done by the sctp_seq_ functions already
>>>> use correct rcu variants.
>>>>
>>>> I don't see this as a problem right now since we either delete the
>>>> transport, or add it. We don't move it to a new location in the list.
>>>> With the move, what could happen is that while sctp_seq_ is printing
>>>> a transport, you might move it to another spot, and the when you grab
>>>> the .next pointer on the next iteration, it points to a completely
>>>> different spot.
>>>>
>>> Ok, I see what you're saying, and looking at the seq code, with your description
>>> I see how we're using half the rcu code to allow the proc interface to avoid
>>> grabbing the socket lock. But this just strikes me a poor coding. Its
>>> confusing to say the least, and begging for mistakes like the one I just made to
>>> be made again. Regardless of necessisty, it seems to me the code would be both
>>> more readable and understandible if we modified it so that we used the rcu api
>>> consistently to access that list.
>>> Neil
>>>
>>
>> Can you elaborate a bit on why you believe we are using half of the
>> rcu code?
>>
> We're using the rcu list add/del apis on the write side when
> we modify the transport_addr_list, but we're using the non-rcu primitives on the
> read side, save for the proc interface.
What other lockless read side do we have?
> Granted that generally safe, exepct for
> any case in which you do exactly what we were speaking about above. I know were
> not doing that now, but it seems to me it would be better to use the rcu
> primitives consistently, so that it was clear how to access the list. It would
> prevent mistakes like the one I just made, as well as other possible mistakes,
> in which future coding errors.
It would cost extra barriers that are completely unnecessary.
>
>> I think to support the move operation you are proposing here, you
>> need something like
>> list_for_each_entry_safe_rcu()
>>
> Not to the best of my knoweldge. Consistent use of the rcu list access
> primitives is safe against rcu list mutation primitives, as long as the read
> side is protected by the rcu_read_lock. As long as thats locked, any mutations
> won't be seen by the read context until after we exit the read side critical
> section.
Not the way I understand rcu. rcu_read_lock will not prevent access to
new contents. This is why list_del_rcu() is careful not to change the
.next pointer.
In the case you are proposing, if the reader is current processing entry
X, and the writer, at the same time moves X to another place, then
at the time the reader looks at X.next, it may point to the new place.
If that happens, you've now corrupted output.
>
>> where the .next pointer is fetched through rcu_dereference() to
>> guard against its possible.
>>
> You won't see the updated next pointer until the read critical side ends. Thats
> why you need to do an rcu_read_lock in addition to grabbing the socket lock.
>
No, that's now how it works. It's based on memory barriers at the time
of deletion/addition and dereference.
-vlad
>> But even that would only work if the move happens to the the earlier
>> spot (like head) of the list. If the move happens to the later part
>> of the list (like tail), you may end up visiting the same list node
>> twice.
>>
> Again, not if you hold the rcu_read_lock. Doing so creates a quiescent point in
> which the status of the list is held until such time as read side critical
> section exits. The move (specifically the delete and the add) won't be seen by
> the reading context until that quiescent point completes, which by definition is
> when that reader is done reading.
>
> Neil
>
>> I think rcu simply can't guard against this.
>>
>> -vlad
>>
>>
> --
> 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: [libvirt] if_bridge.h: include in6.h for struct in6_addr use
From: Eric Blake @ 2013-03-13 16:24 UTC (permalink / raw)
To: Kumar Gala
Cc: Thomas Backlund, netdev, linux-kernel@vger.kernel.org list,
libvirt-list, stephen, Zhenhua Luo
In-Reply-To: <81B30F90-5A18-4386-9C30-E336AE212D85@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 723 bytes --]
On 03/13/2013 09:17 AM, Kumar Gala wrote:
>>>>
>>>> if_bridge.h uses struct in6_addr ip6; but does not include the in6.h
>>>> header.
>>>>
>>>> Found by trying to build libvirt and connman against 3.8-rc3 headers.
>>>>
>>>
> Did this ever get resolved ?
Libvirt has managed to work around the kernel issue in the meantime.
But just today, I hit the same issue with the latest
kernel-headers-3.8.2-206.fc18.x86_64 on Fedora 18 when backporting to an
older libvirt branch that did not have the workaround. A kernel person
would have to speak up for certain, but I think it is still a problem.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] packet: packet fanout rollover during socket overload
From: Willem de Bruijn @ 2013-03-13 16:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Eric Dumazet
In-Reply-To: <20130313.044544.792587152137191597.davem@davemloft.net>
On Wed, Mar 13, 2013 at 4:45 AM, David Miller <davem@davemloft.net> wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 13 Mar 2013 04:44:05 -0400 (EDT)
>
>>
>> My kingdom for a proper signoff.
>
> Nevermind I see you did this in the second copy you posted.
>
> Please mention that such things have changed below the "---"
> seperator so that people can know instead of just guess.
Will do. Apologies for the botched emails, including the html reply
that the list thankfully rejected. I'll write some fanout
documentation for the packet man page as penance.
^ permalink raw reply
* question about creating patch
From: Zhouyi Zhou @ 2013-03-13 16:11 UTC (permalink / raw)
To: netdev
Dear Colleagues,
I have read Kushal Koolwal's article
"HOWTO: Create and submit your first Linux kernel patch using GIT"
and one question remain
which tree is preferable in git://git.kernel.org/pub/scm/ should I
clone in git clone step,
linux/kernel/git/stable/linux-stable.git
or
linux/kernel/git/davem/net.git
Many thanks
Zhouyi
^ permalink raw reply
* Re: [PATCH net-next 0/4] Allow bridge to function in non-promisc mode
From: Stephen Hemminger @ 2013-03-13 16:09 UTC (permalink / raw)
To: vyasevic
Cc: netdev@vger.kernel.org, bridge@lists.linux-foundation.org,
Oleg A. Arkhangelsky
In-Reply-To: <51409F24.3070305@redhat.com>
On Wed, 13 Mar 2013 11:45:40 -0400
Vlad Yasevich <vyasevic@redhat.com> wrote:
> On 03/13/2013 11:39 AM, Stephen Hemminger wrote:
> > On Wed, 13 Mar 2013 08:12:29 -0400
> > Vlad Yasevich <vyasevic@redhat.com> wrote:
> >
> >> On 03/13/2013 02:22 AM, "Oleg A. Arkhangelsky" wrote:
> >>>
> >>>
> >>> 13.03.2013, 05:45, "Vlad Yasevich" <vyasevic@redhat.com>:
> >>>
> >>>> The series adds an ability for the bridge to function in non-promiscuous mode.
> >>>
> >>> What is the practical applications for such setup? In other words,
> >>> in which cases I would want to put bridge into non-promiscuous
> >>> mode and specify some uplink ports?
> >>>
> >>
> >> On of the applications would be when bridge is an edge device servicing
> >> a VM deployment. Each of the VMs knows the mac address that the guest
> >> has and may program that mac onto the uplinks.
> >
> > Why wouldn't that environment just use macvlan?
> > Is it because changing libvirt is harder than changing the kernel?
> >
>
> No, because macvlan has a drawback that it doesn't easily let guests
> talk to the host. Bridge is still most commonly used for just that reason.
>
> -vlad
Maybe fixing that with a flag to macvlan would be easier?
^ permalink raw reply
* Re: [PATCH] Revert "ip_gre: make ipgre_tunnel_xmit() not parse network header as IP unconditionally"
From: Timo Teras @ 2013-03-13 15:56 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: netdev, Eric Dumazet, David S. Miller
In-Reply-To: <20130313150510.GF19577@valinux.co.jp>
On Thu, 14 Mar 2013 00:05:10 +0900
Isaku Yamahata <yamahata@valinux.co.jp> wrote:
> Hi.
>
> On Wed, Mar 13, 2013 at 02:37:49PM +0200, Timo Teräs wrote:
> > This reverts commit 412ed94744d16806fbec3bd250fd94e71cde5a1f.
> >
> > The commit is wrong as tiph points to the outer IPv4 header which is
> > installed at ipgre_header() and not the inner one which is protocol
> > dependant.
> >
> > This commit broke succesfully opennhrp which use PF_PACKET socket
> > with ETH_P_NHRP protocol. Additionally ssl_addr is set to the
> > link-layer IPv4 address. This address is written by ipgre_header()
> > to the skb earlier, and this is the IPv4 header tiph should point
> > to - regardless of the inner protocol payload.
>
> Is this the case only for ETH_P_HNRP?
> I wrote the patch having MPLS over GRE in mind.
> Should it be something like this?
> if (protocol == htons(ETH_P_IP) || protocol == htons(ETH_P_NHRP))
> ....
No, the original code was correct for all protocols.
tiph refers to the IPv4 headers pushed by ip_gre driver in
ipgre_header() function. This is _always_ present regardless of the
inner protocol. Thus no checking for protocol should be done.
And for reference: NHRP does not have iphdr, it is completely different
payload.
What happens is on xmit path is:
1. ipgre_header() is always called first with NBMA destination
address and outer IPv4 + GRE headers are pushed here with
per-packet destination set
2. ipgre_tunnel_xmit() is called, tiph points to the tunnel's
IPv4 header, gre_hlen is set to zero so that the header is not
pushed twice, but the existing header is modified later
Thus, it does not matter if the payload is MPLS, we will not refer to
the mpls data - the skb has already tunnel's outer IPv4 and GRE header
pushed, and tiph will refer to the tunnel's IPv4 header.
- Timo
^ permalink raw reply
* Re: [PATCH net-next] packet: packet fanout rollover during socket overload
From: Willem de Bruijn @ 2013-03-13 15:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, David Miller
In-Reply-To: <1363184717.13690.53.camel@edumazet-glaptop>
On Wed, Mar 13, 2013 at 10:25 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> On Tue, 2013-03-12 at 11:37 -0400, Willem de Bruijn wrote:
> > Minimize packet drop in a fanout group. If one socket is full,
> > roll over packets to another from the group. The intended use is
> > to maintain flow affinity during normal load using an rxhash or
> > cpu fanout policy, while dispersing unexpected traffic storms that
> > hit a single cpu, such as spoofed-source DoS flows. This mechanism
> > breaks affinity for flows arriving at saturated sockets during
> > those conditions.
> >
> > The patch adds a fanout policy ROLLOVER that rotates between sockets,
> > filling each socket before moving to the next. It also adds a fanout
> > flag ROLLOVER. If passed along with any other fanout policy, the
> > primary policy is applied until the chosen socket is full. Then,
> > rollover selects another socket, to delay packet drop until the
> > entire system is saturated.
> >
> > Probing sockets is not free. Selecting the last used socket, as
> > rollover does, is a greedy approach that maximizes chance of
> > success, at the cost of extreme load imbalance. In practice, with
> > sufficiently long queues to handle rate, sockets are drained in
> > parallel and load balance looks uniform in `top`.
> >
> > To avoid contention, scales counters with number of sockets and
> > accesses them lockfree. Values are bounds checked to ensure
> > correctness. An alternative would be to use atomic rr_cur.
> >
> > Tested using an application with 9 threads pinned to CPUs, one socket
> > per thread and sufficient busywork per packet operation to limits each
> > thread to handling 32 Kpps. When sent 500 Kpps single UDP stream
> > packets, a FANOUT_CPU setup processes 32 Kpps in total without this
> > patch, 270 Kpps with the patch. Tested with read() and with a packet
> > ring (V1).
> >
> > Signed-off-by: Willem de Bruijn <willemb@google.com>
> > ---
> > include/linux/if_packet.h | 2 +
> > net/packet/af_packet.c | 112 ++++++++++++++++++++++++++++++++++++----------
> > 2 files changed, 90 insertions(+), 24 deletions(-)
>
>
> > -static struct sock *fanout_demux_cpu(struct packet_fanout *f, struct sk_buff *skb, unsigned int num)
> > +static unsigned int fanout_demux_rollover(struct packet_fanout *f,
> > + struct sk_buff *skb,
> > + unsigned int idx, unsigned int skip,
> > + unsigned int num)
> > {
> > - unsigned int cpu = smp_processor_id();
> > + unsigned int i, j;
> >
> > - return f->arr[cpu % num];
> > + i = j = min(f->next[idx], (int) f->num_members - 1);
>
> min_t(int, f->next[idx], f->num_members - 1);
>
> BTW, num_members can be 0
>
> You really should do
>
> int members = ACCESS_ONCE(f->num_members) - 1;
>
> if (members < 0)
> return idx;
>
> and only use members in your loop.
Thanks for catching that. I'll revise as mentioned.
>
> > + do {
> > + if (i != skip && packet_rcv_has_room(pkt_sk(f->arr[i]), skb)) {
> > + if (i != j)
> > + f->next[idx] = i;
> > + return i;
> > + }
> > + if (++i >= f->num_members)
> > + i = 0;
> > + } while (i != j && idx < f->num_members);
> > +
> > + return idx;
> > +}
> >
+
It is probably also better if the rollover flag always leaves some
room in the socket chosen with f->next. This to ensure that that
socket can still enqueue its own packets, avoiding sending it into
rollover mode, too.
^ permalink raw reply
* Re: [PATCH] net/ieee802154/6lowpan: Fix initialization for fragment offset
From: Alan Ott @ 2013-03-13 15:45 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
Linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <D859EF9A-19A9-4F74-B59D-28FADBCE338A-G+tS6SCNB47quOJu9mQKZg@public.gmane.org>
[-- Attachment #1.1: Type: text/plain, Size: 1280 bytes --]
On 03/13/2013 10:40 AM, Wolf-Bastian Pöttner wrote:
> Nope. The patch fixes a problem in code that is not in mainline yet. However, people on the linux-zigbee mailing list found it a good idea to commit this change to mainline to avoid the problem from arising.
>
> I see, you disagree. Nevermind. ;)
Hi David,
This is my fault. I must have been looking the wrong tree when I
recommended a push to mainline.
Sorry for the noise.
Alan.
> Am 13.03.2013 um 15:38 schrieb David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>:
>> > From: Wolf-Bastian Pöttner <poettner-G+tS6SCNB47quOJu9mQKZg@public.gmane.org>
>> > Date: Wed, 13 Mar 2013 08:50:54 +0100
>> >
>>> >> offset has to be initialized, otherwise the *first* fragment will
>>> >> be discarded and reassembly cannot happen.
>>> >>
>>> >> Reviewed-by: Alan Ott <alan-yzvJWuRpmD1zbRFIqnYvSA@public.gmane.org>
>> >
>> > 'offset' is never used unless lowpan_fetch_skb_u8(skb, &offset)
>> > succeeds, in which case it will be initialized properly. Otherwise we
>> > unlock and drop the SKB and make no references whatsoever to 'offset'.
>> >
>> > I suspect you saw some compiler warning about 'offset' being
>> > uninitialized, and are just blindly trying to shut this warning up.
>
[-- Attachment #1.2: Type: text/html, Size: 3615 bytes --]
[-- Attachment #2: Type: text/plain, Size: 238 bytes --]
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
[-- Attachment #3: Type: text/plain, Size: 213 bytes --]
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel
^ 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