@@ -764,6 +764,27 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = {
764
764
[IFLA_BR_PRIORITY ] = { .type = NLA_U16 },
765
765
[IFLA_BR_VLAN_FILTERING ] = { .type = NLA_U8 },
766
766
[IFLA_BR_VLAN_PROTOCOL ] = { .type = NLA_U16 },
767
+ [IFLA_BR_GROUP_FWD_MASK ] = { .type = NLA_U16 },
768
+ [IFLA_BR_GROUP_ADDR ] = { .type = NLA_BINARY ,
769
+ .len = ETH_ALEN },
770
+ [IFLA_BR_MCAST_ROUTER ] = { .type = NLA_U8 },
771
+ [IFLA_BR_MCAST_SNOOPING ] = { .type = NLA_U8 },
772
+ [IFLA_BR_MCAST_QUERY_USE_IFADDR ] = { .type = NLA_U8 },
773
+ [IFLA_BR_MCAST_QUERIER ] = { .type = NLA_U8 },
774
+ [IFLA_BR_MCAST_HASH_ELASTICITY ] = { .type = NLA_U32 },
775
+ [IFLA_BR_MCAST_HASH_MAX ] = { .type = NLA_U32 },
776
+ [IFLA_BR_MCAST_LAST_MEMBER_CNT ] = { .type = NLA_U32 },
777
+ [IFLA_BR_MCAST_STARTUP_QUERY_CNT ] = { .type = NLA_U32 },
778
+ [IFLA_BR_MCAST_LAST_MEMBER_INTVL ] = { .type = NLA_U64 },
779
+ [IFLA_BR_MCAST_MEMBERSHIP_INTVL ] = { .type = NLA_U64 },
780
+ [IFLA_BR_MCAST_QUERIER_INTVL ] = { .type = NLA_U64 },
781
+ [IFLA_BR_MCAST_QUERY_INTVL ] = { .type = NLA_U64 },
782
+ [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL ] = { .type = NLA_U64 },
783
+ [IFLA_BR_MCAST_STARTUP_QUERY_INTVL ] = { .type = NLA_U64 },
784
+ [IFLA_BR_NF_CALL_IPTABLES ] = { .type = NLA_U8 },
785
+ [IFLA_BR_NF_CALL_IP6TABLES ] = { .type = NLA_U8 },
786
+ [IFLA_BR_NF_CALL_ARPTABLES ] = { .type = NLA_U8 },
787
+ [IFLA_BR_VLAN_DEFAULT_PVID ] = { .type = NLA_U16 },
767
788
};
768
789
769
790
static int br_changelink (struct net_device * brdev , struct nlattr * tb [],
@@ -827,6 +848,158 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
827
848
if (err )
828
849
return err ;
829
850
}
851
+
852
+ if (data [IFLA_BR_VLAN_DEFAULT_PVID ]) {
853
+ __u16 defpvid = nla_get_u16 (data [IFLA_BR_VLAN_DEFAULT_PVID ]);
854
+
855
+ err = __br_vlan_set_default_pvid (br , defpvid );
856
+ if (err )
857
+ return err ;
858
+ }
859
+ #endif
860
+
861
+ if (data [IFLA_BR_GROUP_FWD_MASK ]) {
862
+ u16 fwd_mask = nla_get_u16 (data [IFLA_BR_GROUP_FWD_MASK ]);
863
+
864
+ if (fwd_mask & BR_GROUPFWD_RESTRICTED )
865
+ return - EINVAL ;
866
+ br -> group_fwd_mask = fwd_mask ;
867
+ }
868
+
869
+ if (data [IFLA_BR_GROUP_ADDR ]) {
870
+ u8 new_addr [ETH_ALEN ];
871
+
872
+ if (nla_len (data [IFLA_BR_GROUP_ADDR ]) != ETH_ALEN )
873
+ return - EINVAL ;
874
+ memcpy (new_addr , nla_data (data [IFLA_BR_GROUP_ADDR ]), ETH_ALEN );
875
+ if (!is_link_local_ether_addr (new_addr ))
876
+ return - EINVAL ;
877
+ if (new_addr [5 ] == 1 || /* 802.3x Pause address */
878
+ new_addr [5 ] == 2 || /* 802.3ad Slow protocols */
879
+ new_addr [5 ] == 3 ) /* 802.1X PAE address */
880
+ return - EINVAL ;
881
+ spin_lock_bh (& br -> lock );
882
+ memcpy (br -> group_addr , new_addr , sizeof (br -> group_addr ));
883
+ spin_unlock_bh (& br -> lock );
884
+ br -> group_addr_set = true;
885
+ br_recalculate_fwd_mask (br );
886
+ }
887
+
888
+ if (data [IFLA_BR_FDB_FLUSH ])
889
+ br_fdb_flush (br );
890
+
891
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
892
+ if (data [IFLA_BR_MCAST_ROUTER ]) {
893
+ u8 multicast_router = nla_get_u8 (data [IFLA_BR_MCAST_ROUTER ]);
894
+
895
+ err = br_multicast_set_router (br , multicast_router );
896
+ if (err )
897
+ return err ;
898
+ }
899
+
900
+ if (data [IFLA_BR_MCAST_SNOOPING ]) {
901
+ u8 mcast_snooping = nla_get_u8 (data [IFLA_BR_MCAST_SNOOPING ]);
902
+
903
+ err = br_multicast_toggle (br , mcast_snooping );
904
+ if (err )
905
+ return err ;
906
+ }
907
+
908
+ if (data [IFLA_BR_MCAST_QUERY_USE_IFADDR ]) {
909
+ u8 val ;
910
+
911
+ val = nla_get_u8 (data [IFLA_BR_MCAST_QUERY_USE_IFADDR ]);
912
+ br -> multicast_query_use_ifaddr = !!val ;
913
+ }
914
+
915
+ if (data [IFLA_BR_MCAST_QUERIER ]) {
916
+ u8 mcast_querier = nla_get_u8 (data [IFLA_BR_MCAST_QUERIER ]);
917
+
918
+ err = br_multicast_set_querier (br , mcast_querier );
919
+ if (err )
920
+ return err ;
921
+ }
922
+
923
+ if (data [IFLA_BR_MCAST_HASH_ELASTICITY ]) {
924
+ u32 val = nla_get_u32 (data [IFLA_BR_MCAST_HASH_ELASTICITY ]);
925
+
926
+ br -> hash_elasticity = val ;
927
+ }
928
+
929
+ if (data [IFLA_BR_MCAST_HASH_MAX ]) {
930
+ u32 hash_max = nla_get_u32 (data [IFLA_BR_MCAST_HASH_MAX ]);
931
+
932
+ err = br_multicast_set_hash_max (br , hash_max );
933
+ if (err )
934
+ return err ;
935
+ }
936
+
937
+ if (data [IFLA_BR_MCAST_LAST_MEMBER_CNT ]) {
938
+ u32 val = nla_get_u32 (data [IFLA_BR_MCAST_LAST_MEMBER_CNT ]);
939
+
940
+ br -> multicast_last_member_count = val ;
941
+ }
942
+
943
+ if (data [IFLA_BR_MCAST_STARTUP_QUERY_CNT ]) {
944
+ u32 val = nla_get_u32 (data [IFLA_BR_MCAST_STARTUP_QUERY_CNT ]);
945
+
946
+ br -> multicast_startup_query_count = val ;
947
+ }
948
+
949
+ if (data [IFLA_BR_MCAST_LAST_MEMBER_INTVL ]) {
950
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_LAST_MEMBER_INTVL ]);
951
+
952
+ br -> multicast_last_member_interval = clock_t_to_jiffies (val );
953
+ }
954
+
955
+ if (data [IFLA_BR_MCAST_MEMBERSHIP_INTVL ]) {
956
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_MEMBERSHIP_INTVL ]);
957
+
958
+ br -> multicast_membership_interval = clock_t_to_jiffies (val );
959
+ }
960
+
961
+ if (data [IFLA_BR_MCAST_QUERIER_INTVL ]) {
962
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_QUERIER_INTVL ]);
963
+
964
+ br -> multicast_querier_interval = clock_t_to_jiffies (val );
965
+ }
966
+
967
+ if (data [IFLA_BR_MCAST_QUERY_INTVL ]) {
968
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_QUERY_INTVL ]);
969
+
970
+ br -> multicast_query_interval = clock_t_to_jiffies (val );
971
+ }
972
+
973
+ if (data [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL ]) {
974
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL ]);
975
+
976
+ br -> multicast_query_response_interval = clock_t_to_jiffies (val );
977
+ }
978
+
979
+ if (data [IFLA_BR_MCAST_STARTUP_QUERY_INTVL ]) {
980
+ u64 val = nla_get_u64 (data [IFLA_BR_MCAST_STARTUP_QUERY_INTVL ]);
981
+
982
+ br -> multicast_startup_query_interval = clock_t_to_jiffies (val );
983
+ }
984
+ #endif
985
+ #if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )
986
+ if (data [IFLA_BR_NF_CALL_IPTABLES ]) {
987
+ u8 val = nla_get_u8 (data [IFLA_BR_NF_CALL_IPTABLES ]);
988
+
989
+ br -> nf_call_iptables = val ? true : false;
990
+ }
991
+
992
+ if (data [IFLA_BR_NF_CALL_IP6TABLES ]) {
993
+ u8 val = nla_get_u8 (data [IFLA_BR_NF_CALL_IP6TABLES ]);
994
+
995
+ br -> nf_call_ip6tables = val ? true : false;
996
+ }
997
+
998
+ if (data [IFLA_BR_NF_CALL_ARPTABLES ]) {
999
+ u8 val = nla_get_u8 (data [IFLA_BR_NF_CALL_ARPTABLES ]);
1000
+
1001
+ br -> nf_call_arptables = val ? true : false;
1002
+ }
830
1003
#endif
831
1004
832
1005
return 0 ;
@@ -843,32 +1016,139 @@ static size_t br_get_size(const struct net_device *brdev)
843
1016
nla_total_size (sizeof (u8 )) + /* IFLA_BR_VLAN_FILTERING */
844
1017
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
845
1018
nla_total_size (sizeof (__be16 )) + /* IFLA_BR_VLAN_PROTOCOL */
1019
+ nla_total_size (sizeof (u16 )) + /* IFLA_BR_VLAN_DEFAULT_PVID */
1020
+ #endif
1021
+ nla_total_size (sizeof (u16 )) + /* IFLA_BR_GROUP_FWD_MASK */
1022
+ nla_total_size (sizeof (struct ifla_bridge_id )) + /* IFLA_BR_ROOT_ID */
1023
+ nla_total_size (sizeof (struct ifla_bridge_id )) + /* IFLA_BR_BRIDGE_ID */
1024
+ nla_total_size (sizeof (u16 )) + /* IFLA_BR_ROOT_PORT */
1025
+ nla_total_size (sizeof (u32 )) + /* IFLA_BR_ROOT_PATH_COST */
1026
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_TOPOLOGY_CHANGE */
1027
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_TOPOLOGY_CHANGE_DETECTED */
1028
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_HELLO_TIMER */
1029
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_TCN_TIMER */
1030
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_TOPOLOGY_CHANGE_TIMER */
1031
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_GC_TIMER */
1032
+ nla_total_size (ETH_ALEN ) + /* IFLA_BR_GROUP_ADDR */
1033
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
1034
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_MCAST_ROUTER */
1035
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_MCAST_SNOOPING */
1036
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_MCAST_QUERY_USE_IFADDR */
1037
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_MCAST_QUERIER */
1038
+ nla_total_size (sizeof (u32 )) + /* IFLA_BR_MCAST_HASH_ELASTICITY */
1039
+ nla_total_size (sizeof (u32 )) + /* IFLA_BR_MCAST_HASH_MAX */
1040
+ nla_total_size (sizeof (u32 )) + /* IFLA_BR_MCAST_LAST_MEMBER_CNT */
1041
+ nla_total_size (sizeof (u32 )) + /* IFLA_BR_MCAST_STARTUP_QUERY_CNT */
1042
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_LAST_MEMBER_INTVL */
1043
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_MEMBERSHIP_INTVL */
1044
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_QUERIER_INTVL */
1045
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_QUERY_INTVL */
1046
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_QUERY_RESPONSE_INTVL */
1047
+ nla_total_size (sizeof (u64 )) + /* IFLA_BR_MCAST_STARTUP_QUERY_INTVL */
1048
+ #endif
1049
+ #if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )
1050
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_NF_CALL_IPTABLES */
1051
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_NF_CALL_IP6TABLES */
1052
+ nla_total_size (sizeof (u8 )) + /* IFLA_BR_NF_CALL_ARPTABLES */
846
1053
#endif
847
1054
0 ;
848
1055
}
849
1056
850
1057
static int br_fill_info (struct sk_buff * skb , const struct net_device * brdev )
851
1058
{
852
1059
struct net_bridge * br = netdev_priv (brdev );
1060
+ u64 hello_timer , tcn_timer , topology_change_timer , gc_timer , clockval ;
853
1061
u32 forward_delay = jiffies_to_clock_t (br -> forward_delay );
854
1062
u32 hello_time = jiffies_to_clock_t (br -> hello_time );
855
1063
u32 age_time = jiffies_to_clock_t (br -> max_age );
856
1064
u32 ageing_time = jiffies_to_clock_t (br -> ageing_time );
857
1065
u32 stp_enabled = br -> stp_enabled ;
858
1066
u16 priority = (br -> bridge_id .prio [0 ] << 8 ) | br -> bridge_id .prio [1 ];
1067
+ u16 group_fwd_mask = br -> group_fwd_mask ;
859
1068
u8 vlan_enabled = br_vlan_enabled (br );
1069
+ struct ifla_bridge_id root_id , bridge_id ;
1070
+
1071
+ memset (& bridge_id , 0 , sizeof (bridge_id ));
1072
+ memset (& root_id , 0 , sizeof (root_id ));
1073
+ memcpy (root_id .prio , br -> designated_root .prio , sizeof (root_id .prio ));
1074
+ memcpy (root_id .addr , br -> designated_root .addr , sizeof (root_id .addr ));
1075
+ memcpy (bridge_id .prio , br -> bridge_id .prio , sizeof (bridge_id .prio ));
1076
+ memcpy (bridge_id .addr , br -> bridge_id .addr , sizeof (bridge_id .addr ));
1077
+ hello_timer = br_timer_value (& br -> hello_timer );
1078
+ tcn_timer = br_timer_value (& br -> tcn_timer );
1079
+ topology_change_timer = br_timer_value (& br -> topology_change_timer );
1080
+ gc_timer = br_timer_value (& br -> gc_timer );
1081
+ clockval = 0 ;
860
1082
861
1083
if (nla_put_u32 (skb , IFLA_BR_FORWARD_DELAY , forward_delay ) ||
862
1084
nla_put_u32 (skb , IFLA_BR_HELLO_TIME , hello_time ) ||
863
1085
nla_put_u32 (skb , IFLA_BR_MAX_AGE , age_time ) ||
864
1086
nla_put_u32 (skb , IFLA_BR_AGEING_TIME , ageing_time ) ||
865
1087
nla_put_u32 (skb , IFLA_BR_STP_STATE , stp_enabled ) ||
866
1088
nla_put_u16 (skb , IFLA_BR_PRIORITY , priority ) ||
867
- nla_put_u8 (skb , IFLA_BR_VLAN_FILTERING , vlan_enabled ))
1089
+ nla_put_u8 (skb , IFLA_BR_VLAN_FILTERING , vlan_enabled ) ||
1090
+ nla_put_u16 (skb , IFLA_BR_GROUP_FWD_MASK , group_fwd_mask ) ||
1091
+ nla_put (skb , IFLA_BR_ROOT_ID , sizeof (root_id ), & root_id ) ||
1092
+ nla_put (skb , IFLA_BR_BRIDGE_ID , sizeof (bridge_id ), & bridge_id ) ||
1093
+ nla_put_u16 (skb , IFLA_BR_ROOT_PORT , br -> root_port ) ||
1094
+ nla_put_u32 (skb , IFLA_BR_ROOT_PATH_COST , br -> root_path_cost ) ||
1095
+ nla_put_u8 (skb , IFLA_BR_TOPOLOGY_CHANGE , br -> topology_change ) ||
1096
+ nla_put_u8 (skb , IFLA_BR_TOPOLOGY_CHANGE_DETECTED ,
1097
+ br -> topology_change_detected ) ||
1098
+ nla_put_u64 (skb , IFLA_BR_HELLO_TIMER , hello_timer ) ||
1099
+ nla_put_u64 (skb , IFLA_BR_TCN_TIMER , tcn_timer ) ||
1100
+ nla_put_u64 (skb , IFLA_BR_TOPOLOGY_CHANGE_TIMER ,
1101
+ topology_change_timer ) ||
1102
+ nla_put_u64 (skb , IFLA_BR_GC_TIMER , gc_timer ) ||
1103
+ nla_put (skb , IFLA_BR_GROUP_ADDR , ETH_ALEN , br -> group_addr ))
868
1104
return - EMSGSIZE ;
869
1105
870
1106
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
871
- if (nla_put_be16 (skb , IFLA_BR_VLAN_PROTOCOL , br -> vlan_proto ))
1107
+ if (nla_put_be16 (skb , IFLA_BR_VLAN_PROTOCOL , br -> vlan_proto ) ||
1108
+ nla_put_u16 (skb , IFLA_BR_VLAN_DEFAULT_PVID , br -> default_pvid ))
1109
+ return - EMSGSIZE ;
1110
+ #endif
1111
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
1112
+ if (nla_put_u8 (skb , IFLA_BR_MCAST_ROUTER , br -> multicast_router ) ||
1113
+ nla_put_u8 (skb , IFLA_BR_MCAST_SNOOPING , !br -> multicast_disabled ) ||
1114
+ nla_put_u8 (skb , IFLA_BR_MCAST_QUERY_USE_IFADDR ,
1115
+ br -> multicast_query_use_ifaddr ) ||
1116
+ nla_put_u8 (skb , IFLA_BR_MCAST_QUERIER , br -> multicast_querier ) ||
1117
+ nla_put_u32 (skb , IFLA_BR_MCAST_HASH_ELASTICITY ,
1118
+ br -> hash_elasticity ) ||
1119
+ nla_put_u32 (skb , IFLA_BR_MCAST_HASH_MAX , br -> hash_max ) ||
1120
+ nla_put_u32 (skb , IFLA_BR_MCAST_LAST_MEMBER_CNT ,
1121
+ br -> multicast_last_member_count ) ||
1122
+ nla_put_u32 (skb , IFLA_BR_MCAST_STARTUP_QUERY_CNT ,
1123
+ br -> multicast_startup_query_count ))
1124
+ return - EMSGSIZE ;
1125
+
1126
+ clockval = jiffies_to_clock_t (br -> multicast_last_member_interval );
1127
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_LAST_MEMBER_INTVL , clockval ))
1128
+ return - EMSGSIZE ;
1129
+ clockval = jiffies_to_clock_t (br -> multicast_membership_interval );
1130
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_MEMBERSHIP_INTVL , clockval ))
1131
+ return - EMSGSIZE ;
1132
+ clockval = jiffies_to_clock_t (br -> multicast_querier_interval );
1133
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_QUERIER_INTVL , clockval ))
1134
+ return - EMSGSIZE ;
1135
+ clockval = jiffies_to_clock_t (br -> multicast_query_interval );
1136
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_QUERY_INTVL , clockval ))
1137
+ return - EMSGSIZE ;
1138
+ clockval = jiffies_to_clock_t (br -> multicast_query_response_interval );
1139
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_QUERY_RESPONSE_INTVL , clockval ))
1140
+ return - EMSGSIZE ;
1141
+ clockval = jiffies_to_clock_t (br -> multicast_startup_query_interval );
1142
+ if (nla_put_u64 (skb , IFLA_BR_MCAST_STARTUP_QUERY_INTVL , clockval ))
1143
+ return - EMSGSIZE ;
1144
+ #endif
1145
+ #if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )
1146
+ if (nla_put_u8 (skb , IFLA_BR_NF_CALL_IPTABLES ,
1147
+ br -> nf_call_iptables ? 1 : 0 ) ||
1148
+ nla_put_u8 (skb , IFLA_BR_NF_CALL_IP6TABLES ,
1149
+ br -> nf_call_ip6tables ? 1 : 0 ) ||
1150
+ nla_put_u8 (skb , IFLA_BR_NF_CALL_ARPTABLES ,
1151
+ br -> nf_call_arptables ? 1 : 0 ))
872
1152
return - EMSGSIZE ;
873
1153
#endif
874
1154
0 commit comments