From 3fef7a3fcdcaa6bc6b4bea9d76f994d8f6385487 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 18 Apr 2016 17:15:52 +0530 Subject: [PATCH] networkd: allow setting of multicast querier for linux bridge (#3051) --- man/systemd.netdev.xml | 11 ++++++ src/basic/missing.h | 35 +++++++++++++++++- src/libsystemd/sd-netlink/netlink-types.c | 43 +++++++++++++++++++---- src/network/networkd-netdev-bridge.c | 17 +++++++++ src/network/networkd-netdev-bridge.h | 2 ++ src/network/networkd-netdev-gperf.gperf | 1 + 6 files changed, 102 insertions(+), 7 deletions(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index c5fb2fa7fb..48c283c8df 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -310,6 +310,17 @@ of the Listening and Learning states before the Forwarding state is entered. + + MulticastQuerier= + + A boolean. This setting controls the IFLA_BR_MCAST_QUERIER option in the kernel. + If enabled, the kernel will send general ICMP queries from a zero source address. + This feature should allow faster convergence on startup, but it causes some + multicast-aware switches to misbehave and disrupt forwarding of multicast packets. + When unset, the kernel's default setting applies. + + + diff --git a/src/basic/missing.h b/src/basic/missing.h index 66cd5921ad..6a49ccd281 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -746,7 +746,40 @@ struct btrfs_ioctl_quota_ctl_args { #define IFLA_BR_AGEING_TIME 4 #define IFLA_BR_STP_STATE 5 #define IFLA_BR_PRIORITY 6 -#define __IFLA_BR_MAX 7 +#define IFLA_BR_VLAN_FILTERING 7 +#define IFLA_BR_VLAN_PROTOCOL 8 +#define IFLA_BR_GROUP_FWD_MASK 9 +#define IFLA_BR_ROOT_ID 10 +#define IFLA_BR_BRIDGE_ID 11 +#define IFLA_BR_ROOT_PORT 12 +#define IFLA_BR_ROOT_PATH_COST 13 +#define IFLA_BR_TOPOLOGY_CHANGE 14 +#define IFLA_BR_TOPOLOGY_CHANGE_DETECTED 15 +#define IFLA_BR_HELLO_TIMER 16 +#define IFLA_BR_TCN_TIMER 17 +#define IFLA_BR_TOPOLOGY_CHANGE_TIMER 18 +#define IFLA_BR_GC_TIMER 19 +#define IFLA_BR_GROUP_ADDR 20 +#define IFLA_BR_FDB_FLUSH 21 +#define IFLA_BR_MCAST_ROUTER 22 +#define IFLA_BR_MCAST_SNOOPING 23 +#define IFLA_BR_MCAST_QUERY_USE_IFADDR 24 +#define IFLA_BR_MCAST_QUERIER 25 +#define IFLA_BR_MCAST_HASH_ELASTICITY 26 +#define IFLA_BR_MCAST_HASH_MAX 27 +#define IFLA_BR_MCAST_LAST_MEMBER_CNT 28 +#define IFLA_BR_MCAST_STARTUP_QUERY_CNT 29 +#define IFLA_BR_MCAST_LAST_MEMBER_INTVL 30 +#define IFLA_BR_MCAST_MEMBERSHIP_INTVL 31 +#define IFLA_BR_MCAST_QUERIER_INTVL 32 +#define IFLA_BR_MCAST_QUERY_INTVL 33 +#define IFLA_BR_MCAST_QUERY_RESPONSE_INTVL 34 +#define IFLA_BR_MCAST_STARTUP_QUERY_INTVL 35 +#define IFLA_BR_NF_CALL_IPTABLES 36 +#define IFLA_BR_NF_CALL_IP6TABLES 37 +#define IFLA_BR_NF_CALL_ARPTABLES 38 +#define IFLA_BR_VLAN_DEFAULT_PVID 39 +#define __IFLA_BR_MAX 40 #define IFLA_BR_MAX (__IFLA_BR_MAX - 1) #endif diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index a5758bb516..3a4bac2ced 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -95,12 +95,43 @@ static const NLType rtnl_link_info_data_macvlan_types[] = { }; static const NLType rtnl_link_info_data_bridge_types[] = { - [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_vlan_types[] = { diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c index cdcd08f057..3f91b2eaea 100644 --- a/src/network/networkd-netdev-bridge.c +++ b/src/network/networkd-netdev-bridge.c @@ -89,6 +89,12 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m"); } + if (b->mcast_querier >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_QUERIER, b->mcast_querier); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_QUERIER attribute: %m"); + } + r = sd_netlink_message_close_container(req); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); @@ -106,8 +112,19 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess return r; } +static void bridge_init(NetDev *n) { + Bridge *b; + + b = BRIDGE(n); + + assert(b); + + b->mcast_querier = -1; +} + const NetDevVTable bridge_vtable = { .object_size = sizeof(Bridge), + .init = bridge_init, .sections = "Match\0NetDev\0Bridge\0", .post_create = netdev_bridge_post_create, .create_type = NETDEV_CREATE_MASTER, diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h index 27f26f7870..3f6f1d0502 100644 --- a/src/network/networkd-netdev-bridge.h +++ b/src/network/networkd-netdev-bridge.h @@ -26,6 +26,8 @@ typedef struct Bridge Bridge; struct Bridge { NetDev meta; + int mcast_querier; + usec_t forward_delay; usec_t hello_time; usec_t max_age; diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index 8f506af092..15a787a9e3 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -92,3 +92,4 @@ Bond.LearnPacketIntervalSec, config_parse_sec, 0, Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) +Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)