From f55fa86dc7e1473071cd3e556d6ae8273bf06fef Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 28 Sep 2014 16:28:00 -0700 Subject: [PATCH 1/3] update headers to 3.17.0 net-next --- include/linux/if_ether.h | 1 + include/linux/if_link.h | 12 ++++++++++++ include/linux/if_tunnel.h | 16 ++++++++++++++++ include/linux/xfrm.h | 7 +++++++ 4 files changed, 36 insertions(+) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index fff06238..4678e499 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -128,6 +128,7 @@ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ #define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */ +#define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */ /* * This is an Ethernet frame header. diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 39cb62ce..e9e6f03f 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -213,6 +213,18 @@ enum in6_addr_gen_mode { IN6_ADDR_GEN_MODE_NONE, }; +/* Bridge section */ + +enum { + IFLA_BR_UNSPEC, + IFLA_BR_FORWARD_DELAY, + IFLA_BR_HELLO_TIME, + IFLA_BR_MAX_AGE, + __IFLA_BR_MAX, +}; + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) + enum { BRIDGE_MODE_UNSPEC, BRIDGE_MODE_HAIRPIN, diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 3e425f9d..32a754bd 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -53,10 +53,22 @@ enum { IFLA_IPTUN_6RD_RELAY_PREFIX, IFLA_IPTUN_6RD_PREFIXLEN, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, + IFLA_IPTUN_ENCAP_TYPE, + IFLA_IPTUN_ENCAP_FLAGS, + IFLA_IPTUN_ENCAP_SPORT, + IFLA_IPTUN_ENCAP_DPORT, __IFLA_IPTUN_MAX, }; #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) +enum tunnel_encap_types { + TUNNEL_ENCAP_NONE, + TUNNEL_ENCAP_FOU, +}; + +#define TUNNEL_ENCAP_FLAG_CSUM (1<<0) +#define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1) + /* SIT-mode i_flags */ #define SIT_ISATAP 0x0001 @@ -94,6 +106,10 @@ enum { IFLA_GRE_ENCAP_LIMIT, IFLA_GRE_FLOWINFO, IFLA_GRE_FLAGS, + IFLA_GRE_ENCAP_TYPE, + IFLA_GRE_ENCAP_FLAGS, + IFLA_GRE_ENCAP_SPORT, + IFLA_GRE_ENCAP_DPORT, __IFLA_GRE_MAX, }; diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index fa2ecb2e..3a1fd329 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -328,6 +328,8 @@ enum xfrm_spdattr_type_t { XFRMA_SPD_UNSPEC, XFRMA_SPD_INFO, XFRMA_SPD_HINFO, + XFRMA_SPD_IPV4_HTHRESH, + XFRMA_SPD_IPV6_HTHRESH, __XFRMA_SPD_MAX #define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1) @@ -347,6 +349,11 @@ struct xfrmu_spdhinfo { __u32 spdhmcnt; }; +struct xfrmu_spdhthresh { + __u8 lbits; + __u8 rbits; +}; + struct xfrm_usersa_info { struct xfrm_selector sel; struct xfrm_id id; From 8c39db391d21ad118e9f2fd6d35f097dea01cdf4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sun, 28 Sep 2014 16:31:04 -0700 Subject: [PATCH 2/3] add bridge_slave device support Note this depends on "iproute2: allow to change slave options via type_slave" --- ip/Makefile | 3 +- ip/iplink_bridge_slave.c | 181 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 ip/iplink_bridge_slave.c diff --git a/ip/Makefile b/ip/Makefile index 36aab479..844639e4 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -5,7 +5,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vlan.o link_veth.o link_gre.o iplink_can.o \ iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o link_vti6.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ - link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o + link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ + iplink_bridge_slave.o RTMONOBJ=rtmon.o diff --git a/ip/iplink_bridge_slave.c b/ip/iplink_bridge_slave.c new file mode 100644 index 00000000..a2851855 --- /dev/null +++ b/ip/iplink_bridge_slave.c @@ -0,0 +1,181 @@ +/* + * iplink_bridge_slave.c Bridge slave device support + * + * 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: Jiri Pirko + */ + +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" + +static void explain(void) +{ + fprintf(stderr, + "Usage: ... bridge_slave [ state STATE ] [ priority PRIO ] [cost COST ]\n" + " [ guard {on | off} ]\n" + " [ hairpin {on | off} ] \n" + " [ fastleave {on | off} ]\n" + " [ root_block {on | off} ]\n" + " [ learning {on | off} ]\n" + " [ flood {on | off} ]\n" + ); +} + +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", +}; + +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_onoff(FILE *f, char *flag, __u8 val) +{ + fprintf(f, "%s %s ", flag, val ? "on" : "off"); +} + +static void bridge_slave_print_opt(struct link_util *lu, FILE *f, + struct rtattr *tb[]) +{ + if (!tb) + return; + + if (tb[IFLA_BRPORT_STATE]) + print_portstate(f, rta_getattr_u8(tb[IFLA_BRPORT_STATE])); + + if (tb[IFLA_BRPORT_PRIORITY]) + fprintf(f, "priority %d ", + rta_getattr_u16(tb[IFLA_BRPORT_PRIORITY])); + + if (tb[IFLA_BRPORT_COST]) + fprintf(f, "cost %d ", + rta_getattr_u32(tb[IFLA_BRPORT_COST])); + + if (tb[IFLA_BRPORT_MODE]) + print_onoff(f, "hairpin", + rta_getattr_u8(tb[IFLA_BRPORT_MODE])); + + if (tb[IFLA_BRPORT_GUARD]) + print_onoff(f, "guard", + rta_getattr_u8(tb[IFLA_BRPORT_GUARD])); + + if (tb[IFLA_BRPORT_PROTECT]) + print_onoff(f, "root_block", + rta_getattr_u8(tb[IFLA_BRPORT_PROTECT])); + + if (tb[IFLA_BRPORT_FAST_LEAVE]) + print_onoff(f, "fastleave", + rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE])); + + if (tb[IFLA_BRPORT_LEARNING]) + print_onoff(f, "learning", + rta_getattr_u8(tb[IFLA_BRPORT_LEARNING])); + + if (tb[IFLA_BRPORT_UNICAST_FLOOD]) + print_onoff(f, "flood", + rta_getattr_u8(tb[IFLA_BRPORT_UNICAST_FLOOD])); +} + +static void bridge_slave_parse_on_off(char *arg_name, char *arg_val, + struct nlmsghdr *n, int type) +{ + __u8 val; + + if (strcmp(arg_val, "on") == 0) + val = 1; + else if (strcmp(arg_val, "off") == 0) + val = 0; + else + invarg("should be \"on\" or \"off\"", arg_name); + + addattr8(n, 1024, type, val); +} + +static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + __u8 state; + __u16 priority; + __u32 cost; + + while (argc > 0) { + if (matches(*argv, "state") == 0) { + NEXT_ARG(); + if (get_u8(&state, *argv, 0)) + invarg("state is invalid", *argv); + addattr8(n, 1024, IFLA_BRPORT_STATE, state); + } else if (matches(*argv, "priority") == 0) { + NEXT_ARG(); + if (get_u16(&priority, *argv, 0)) + invarg("priority is invalid", *argv); + addattr16(n, 1024, IFLA_BRPORT_PRIORITY, priority); + } else if (matches(*argv, "cost") == 0) { + NEXT_ARG(); + if (get_u32(&cost, *argv, 0)) + invarg("cost is invalid", *argv); + addattr32(n, 1024, IFLA_BRPORT_COST, cost); + } else if (matches(*argv, "hairpin") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("hairpin", *argv, n, + IFLA_BRPORT_MODE); + } else if (matches(*argv, "guard") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("guard", *argv, n, + IFLA_BRPORT_GUARD); + } else if (matches(*argv, "root_block") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("root_block", *argv, n, + IFLA_BRPORT_PROTECT); + } else if (matches(*argv, "fastleave") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("fastleave", *argv, n, + IFLA_BRPORT_FAST_LEAVE); + } else if (matches(*argv, "learning") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("learning", *argv, n, + IFLA_BRPORT_LEARNING); + } else if (matches(*argv, "flood") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("flood", *argv, n, + IFLA_BRPORT_UNICAST_FLOOD); + } else if (matches(*argv, "help") == 0) { + explain(); + return -1; + } else { + fprintf(stderr, "bridge_slave: unknown option \"%s\"?\n", + *argv); + explain(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +struct link_util bridge_slave_link_util = { + .id = "bridge", + .maxattr = IFLA_BRPORT_MAX, + .print_opt = bridge_slave_print_opt, + .parse_opt = bridge_slave_parse_opt, + .slave = true, +}; From 28d84b429e4e20e63f6e4746285ccfdb72eac92f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sun, 28 Sep 2014 16:33:29 -0700 Subject: [PATCH 3/3] add bridge master device support Signed-off-by: Jiri Pirko --- ip/Makefile | 2 +- ip/iplink_bridge.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 ip/iplink_bridge.c diff --git a/ip/Makefile b/ip/Makefile index 844639e4..5405ee7e 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -6,7 +6,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o link_vti6.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ - iplink_bridge_slave.o + iplink_bridge.o iplink_bridge_slave.o RTMONOBJ=rtmon.o diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c new file mode 100644 index 00000000..0cea7d1f --- /dev/null +++ b/ip/iplink_bridge.c @@ -0,0 +1,93 @@ +/* + * iplink_bridge.c Bridge device support + * + * 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: Jiri Pirko + */ + +#include +#include +#include +#include + +#include "utils.h" +#include "ip_common.h" + +static void explain(void) +{ + fprintf(stderr, + "Usage: ... bridge [ forward_delay FORWARD_DELAY ]\n" + " [ hello_time HELLO_TIME ]\n" + " [ max_age MAX_AGE ]\n" + ); +} + +static int bridge_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + __u32 val; + + while (argc > 0) { + if (matches(*argv, "forward_delay") == 0) { + NEXT_ARG(); + if (get_u32(&val, *argv, 0)) { + invarg("invalid forward_delay", *argv); + return -1; + } + addattr32(n, 1024, IFLA_BR_FORWARD_DELAY, val); + } else if (matches(*argv, "hello_time") == 0) { + NEXT_ARG(); + if (get_u32(&val, *argv, 0)) { + invarg("invalid hello_time", *argv); + return -1; + } + addattr32(n, 1024, IFLA_BR_HELLO_TIME, val); + } else if (matches(*argv, "max_age") == 0) { + NEXT_ARG(); + if (get_u32(&val, *argv, 0)) { + invarg("invalid max_age", *argv); + return -1; + } + addattr32(n, 1024, IFLA_BR_MAX_AGE, val); + } else if (matches(*argv, "help") == 0) { + explain(); + return -1; + } else { + fprintf(stderr, "bridge: unknown command \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) +{ + if (!tb) + return; + + if (tb[IFLA_BR_FORWARD_DELAY]) + fprintf(f, "forward_delay %u ", + rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY])); + + if (tb[IFLA_BR_HELLO_TIME]) + fprintf(f, "hello_time %u ", + rta_getattr_u32(tb[IFLA_BR_HELLO_TIME])); + + if (tb[IFLA_BR_MAX_AGE]) + fprintf(f, "max_age %u ", + rta_getattr_u32(tb[IFLA_BR_MAX_AGE])); +} + +struct link_util bridge_link_util = { + .id = "bridge", + .maxattr = IFLA_BR_MAX, + .parse_opt = bridge_parse_opt, + .print_opt = bridge_print_opt, +};