]>
Commit | Line | Data |
---|---|---|
697b4f04 MT |
1 | From 9bad339af848fc30bab4ea2759f022820f474e17 Mon Sep 17 00:00:00 2001 |
2 | From: Neil Jerram <Neil.Jerram@metaswitch.com> | |
3 | Date: Wed, 10 Jun 2015 22:16:35 +0100 | |
4 | Subject: [PATCH 110/113] Apply --bridge-interfaces to unsolicited router | |
5 | advertisements. | |
6 | ||
7 | --- | |
8 | src/radv.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- | |
9 | 1 file changed, 84 insertions(+), 2 deletions(-) | |
10 | ||
11 | diff --git a/src/radv.c b/src/radv.c | |
12 | index 54784967df57..300c31c83c78 100644 | |
13 | --- a/src/radv.c | |
14 | +++ b/src/radv.c | |
15 | @@ -40,9 +40,18 @@ struct search_param { | |
16 | char name[IF_NAMESIZE+1]; | |
17 | }; | |
18 | ||
19 | +struct alias_param { | |
20 | + int iface; | |
21 | + struct dhcp_bridge *bridge; | |
22 | + int num_alias_ifs; | |
23 | + int max_alias_ifs; | |
24 | + int *alias_ifs; | |
25 | +}; | |
26 | + | |
27 | static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest); | |
28 | static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_addr *dest, | |
29 | int send_iface); | |
30 | +static int send_ra_to_aliases(int index, unsigned int type, char *mac, size_t maclen, void *parm); | |
31 | static int add_prefixes(struct in6_addr *local, int prefix, | |
32 | int scope, int if_index, int flags, | |
33 | unsigned int preferred, unsigned int valid, void *vparam); | |
34 | @@ -723,6 +732,7 @@ time_t periodic_ra(time_t now) | |
35 | struct search_param param; | |
36 | struct dhcp_context *context; | |
37 | time_t next_event; | |
38 | + struct alias_param aparam; | |
39 | ||
40 | param.now = now; | |
41 | param.iface = 0; | |
42 | @@ -770,12 +780,84 @@ time_t periodic_ra(time_t now) | |
43 | if (tmp->name && wildcard_match(tmp->name, param.name)) | |
44 | break; | |
45 | if (!tmp) | |
46 | - send_ra(now, param.iface, param.name, NULL); | |
47 | + { | |
48 | + send_ra(now, param.iface, param.name, NULL); | |
49 | + | |
50 | + /* Also send on all interfaces that are aliases of this | |
51 | + one. */ | |
52 | + for (aparam.bridge = daemon->bridges; | |
53 | + aparam.bridge; | |
54 | + aparam.bridge = aparam.bridge->next) | |
55 | + if ((int)if_nametoindex(aparam.bridge->iface) == param.iface) | |
56 | + { | |
57 | + /* Count the number of alias interfaces for this | |
58 | + 'bridge', by calling iface_enumerate with | |
59 | + send_ra_to_aliases and NULL alias_ifs. */ | |
60 | + aparam.iface = param.iface; | |
61 | + aparam.alias_ifs = NULL; | |
62 | + aparam.num_alias_ifs = 0; | |
63 | + iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases); | |
64 | + my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => %d alias(es)", | |
65 | + param.name, daemon->addrbuff, aparam.num_alias_ifs); | |
66 | + | |
67 | + /* Allocate memory to store the alias interface | |
68 | + indices. */ | |
69 | + aparam.alias_ifs = (int *)whine_malloc(aparam.num_alias_ifs * | |
70 | + sizeof(int)); | |
71 | + if (aparam.alias_ifs) | |
72 | + { | |
73 | + /* Use iface_enumerate again to get the alias | |
74 | + interface indices, then send on each of | |
75 | + those. */ | |
76 | + aparam.max_alias_ifs = aparam.num_alias_ifs; | |
77 | + aparam.num_alias_ifs = 0; | |
78 | + iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases); | |
79 | + for (; aparam.num_alias_ifs; aparam.num_alias_ifs--) | |
80 | + { | |
81 | + my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => i/f %d", | |
82 | + param.name, daemon->addrbuff, | |
83 | + aparam.alias_ifs[aparam.num_alias_ifs - 1]); | |
84 | + send_ra_alias(now, | |
85 | + param.iface, | |
86 | + param.name, | |
87 | + NULL, | |
88 | + aparam.alias_ifs[aparam.num_alias_ifs - 1]); | |
89 | + } | |
90 | + free(aparam.alias_ifs); | |
91 | + } | |
92 | + | |
93 | + /* The source interface can only appear in at most | |
94 | + one --bridge-interfaces. */ | |
95 | + break; | |
96 | + } | |
97 | + } | |
98 | } | |
99 | } | |
100 | return next_event; | |
101 | } | |
102 | - | |
103 | + | |
104 | +static int send_ra_to_aliases(int index, unsigned int type, char *mac, size_t maclen, void *parm) | |
105 | +{ | |
106 | + struct alias_param *aparam = (struct alias_param *)parm; | |
107 | + char ifrn_name[IFNAMSIZ]; | |
108 | + struct dhcp_bridge *alias; | |
109 | + | |
110 | + (void)type; | |
111 | + (void)mac; | |
112 | + (void)maclen; | |
113 | + | |
114 | + if (if_indextoname(index, ifrn_name)) | |
115 | + for (alias = aparam->bridge->alias; alias; alias = alias->next) | |
116 | + if (wildcard_matchn(alias->iface, ifrn_name, IFNAMSIZ)) | |
117 | + { | |
118 | + if (aparam->alias_ifs && (aparam->num_alias_ifs < aparam->max_alias_ifs)) | |
119 | + aparam->alias_ifs[aparam->num_alias_ifs] = index; | |
120 | + aparam->num_alias_ifs++; | |
121 | + } | |
122 | + | |
123 | + return 1; | |
124 | +} | |
125 | + | |
126 | static int iface_search(struct in6_addr *local, int prefix, | |
127 | int scope, int if_index, int flags, | |
128 | int preferred, int valid, void *vparam) | |
129 | -- | |
130 | 2.1.0 | |
131 |