br_multicast.c (eb1d16414339a6e113d89e2cca2556005d7ce919) | br_multicast.c (0909e11758bd28848aeb6646e021ec1e031a3f0f) |
---|---|
1/* 2 * Bridge multicast support. 3 * 4 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) --- 732 unchanged lines hidden (view full) --- 741 err = br_multicast_add_group(br, port, group); 742 if (err) 743 break; 744 } 745 746 return err; 747} 748 | 1/* 2 * Bridge multicast support. 3 * 4 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) --- 732 unchanged lines hidden (view full) --- 741 err = br_multicast_add_group(br, port, group); 742 if (err) 743 break; 744 } 745 746 return err; 747} 748 |
749static void br_multicast_add_router(struct net_bridge *br, 750 struct net_bridge_port *port) 751{ 752 struct hlist_node *p; 753 struct hlist_node **h; 754 755 for (h = &br->router_list.first; 756 (p = *h) && 757 (unsigned long)container_of(p, struct net_bridge_port, rlist) > 758 (unsigned long)port; 759 h = &p->next) 760 ; 761 762 port->rlist.pprev = h; 763 port->rlist.next = p; 764 rcu_assign_pointer(*h, &port->rlist); 765 if (p) 766 p->pprev = &port->rlist.next; 767} 768 |
|
749static void br_multicast_mark_router(struct net_bridge *br, 750 struct net_bridge_port *port) 751{ 752 unsigned long now = jiffies; | 769static void br_multicast_mark_router(struct net_bridge *br, 770 struct net_bridge_port *port) 771{ 772 unsigned long now = jiffies; |
753 struct hlist_node *p; 754 struct hlist_node **h; | |
755 756 if (!port) { 757 if (br->multicast_router == 1) 758 mod_timer(&br->multicast_router_timer, 759 now + br->multicast_querier_interval); 760 return; 761 } 762 763 if (port->multicast_router != 1) 764 return; 765 766 if (!hlist_unhashed(&port->rlist)) 767 goto timer; 768 | 773 774 if (!port) { 775 if (br->multicast_router == 1) 776 mod_timer(&br->multicast_router_timer, 777 now + br->multicast_querier_interval); 778 return; 779 } 780 781 if (port->multicast_router != 1) 782 return; 783 784 if (!hlist_unhashed(&port->rlist)) 785 goto timer; 786 |
769 for (h = &br->router_list.first; 770 (p = *h) && 771 (unsigned long)container_of(p, struct net_bridge_port, rlist) > 772 (unsigned long)port; 773 h = &p->next) 774 ; | 787 br_multicast_add_router(br, port); |
775 | 788 |
776 port->rlist.pprev = h; 777 port->rlist.next = p; 778 rcu_assign_pointer(*h, &port->rlist); 779 if (p) 780 p->pprev = &port->rlist.next; 781 | |
782timer: 783 mod_timer(&port->multicast_router_timer, 784 now + br->multicast_querier_interval); 785} 786 787static void br_multicast_query_received(struct net_bridge *br, 788 struct net_bridge_port *port, 789 __be32 saddr) --- 338 unchanged lines hidden (view full) --- 1128 } 1129 1130 mdb->old = mdb; 1131 call_rcu_bh(&mdb->rcu, br_mdb_free); 1132 1133out: 1134 spin_unlock_bh(&br->multicast_lock); 1135} | 789timer: 790 mod_timer(&port->multicast_router_timer, 791 now + br->multicast_querier_interval); 792} 793 794static void br_multicast_query_received(struct net_bridge *br, 795 struct net_bridge_port *port, 796 __be32 saddr) --- 338 unchanged lines hidden (view full) --- 1135 } 1136 1137 mdb->old = mdb; 1138 call_rcu_bh(&mdb->rcu, br_mdb_free); 1139 1140out: 1141 spin_unlock_bh(&br->multicast_lock); 1142} |
1143 1144int br_multicast_set_router(struct net_bridge *br, unsigned long val) 1145{ 1146 int err = -ENOENT; 1147 1148 spin_lock_bh(&br->multicast_lock); 1149 if (!netif_running(br->dev)) 1150 goto unlock; 1151 1152 switch (val) { 1153 case 0: 1154 case 2: 1155 del_timer(&br->multicast_router_timer); 1156 /* fall through */ 1157 case 1: 1158 br->multicast_router = val; 1159 err = 0; 1160 break; 1161 1162 default: 1163 err = -EINVAL; 1164 break; 1165 } 1166 1167unlock: 1168 spin_unlock_bh(&br->multicast_lock); 1169 1170 return err; 1171} 1172 1173int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) 1174{ 1175 struct net_bridge *br = p->br; 1176 int err = -ENOENT; 1177 1178 spin_lock(&br->multicast_lock); 1179 if (!netif_running(br->dev) || p->state == BR_STATE_DISABLED) 1180 goto unlock; 1181 1182 switch (val) { 1183 case 0: 1184 case 1: 1185 case 2: 1186 p->multicast_router = val; 1187 err = 0; 1188 1189 if (val < 2 && !hlist_unhashed(&p->rlist)) 1190 hlist_del_init_rcu(&p->rlist); 1191 1192 if (val == 1) 1193 break; 1194 1195 del_timer(&p->multicast_router_timer); 1196 1197 if (val == 0) 1198 break; 1199 1200 br_multicast_add_router(br, p); 1201 break; 1202 1203 default: 1204 err = -EINVAL; 1205 break; 1206 } 1207 1208unlock: 1209 spin_unlock(&br->multicast_lock); 1210 1211 return err; 1212} |
|