FD.io VPP  v18.07-34-g55fbdb9
Vector Packet Processing
igmp_report.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #include <igmp/igmp_report.h>
19 #include <igmp/igmp_pkt.h>
20 
21 static ip46_address_t *
23 {
24  ip46_address_t *srcs = NULL;
25  const ip4_address_t *s;
26  u16 ii, n;
27 
28  /*
29  * we validated this packet when we accepted it in the DP, so
30  * this number is safe to use
31  */
32  n = clib_net_to_host_u16 (r->n_src_addresses);
33 
34  if (0 == n)
35  return (NULL);
36 
37  vec_validate (srcs, n - 1);
38  s = r->src_addresses;
39 
40  for (ii = 0; ii < n; ii++)
41  {
42  srcs[ii].ip4 = *s;
43  s++;
44  }
45 
46  return (srcs);
47 }
48 
49 static void
51  const igmp_membership_group_v3_t * igmp_group)
52 {
53  ip46_address_t *src, *srcs;
54  igmp_group_t *group;
55  ip46_address_t key = {
56  .ip4 = igmp_group->group_address,
57  };
58 
59  srcs = igmp_group_mk_source_list (igmp_group);
60  group = igmp_group_lookup (config, &key);
61 
62  IGMP_DBG (" ..group-update: %U (%U, %U)",
64  vnet_get_main (), config->sw_if_index,
66 
67  if (NULL == group)
68  {
69  group = igmp_group_alloc (config, &key, IGMP_FILTER_MODE_INCLUDE);
70  }
71 
72  /* create or update all sources */
73  vec_foreach (src, srcs)
74  {
75  igmp_group_src_update (group, src, IGMP_MODE_ROUTER);
76  }
77 
78  vec_free (srcs);
79 }
80 
81 static void
83  const igmp_membership_group_v3_t * igmp_group)
84 {
85  ip46_address_t *s, *srcs;
87  igmp_group_t *group;
88  ip46_address_t key = {
89  .ip4 = igmp_group->group_address,
90  };
91 
92  srcs = igmp_group_mk_source_list (igmp_group);
93  group = igmp_group_lookup (config, &key);
94 
95  IGMP_DBG (" ..group-block: %U (%U, %U)",
97  vnet_get_main (), config->sw_if_index,
99 
100  if (group)
101  {
102  igmp_src_t *src;
103  /*
104  * sned a group+source specific query
105  */
106  igmp_pkt_build_query_init (&bq, config->sw_if_index);
107  igmp_pkt_query_v3_add_group (&bq, group, srcs);
109 
110  /*
111  * for each source left/blocked drop the source expire timer to the leave
112  * latency timer
113  */
114  vec_foreach (s, srcs)
115  {
116  src = igmp_src_lookup (group, s);
117  if (NULL != src)
118  igmp_src_blocked (src);
119  }
120  }
121  /*
122  * a block/leave from a group for which we have no state
123  */
124 
125  vec_free (srcs);
126 }
127 
128 static void
130  const igmp_membership_group_v3_t * igmp_group)
131 {
132  IGMP_DBG ("rx-group-report: %U",
134  vnet_get_main (), config->sw_if_index);
135 
136  switch (igmp_group->type)
137  {
138  case IGMP_MEMBERSHIP_GROUP_mode_is_include:
139  case IGMP_MEMBERSHIP_GROUP_change_to_include:
140  case IGMP_MEMBERSHIP_GROUP_allow_new_sources:
141  igmp_handle_group_update (config, igmp_group);
142  break;
143  case IGMP_MEMBERSHIP_GROUP_block_old_sources:
144  igmp_handle_group_block (config, igmp_group);
145  break;
146  case IGMP_MEMBERSHIP_GROUP_mode_is_exclude:
147  case IGMP_MEMBERSHIP_GROUP_change_to_exclude:
148  break;
149  /*
150  * all other types ignored
151  */
152  }
153 }
154 
155 void
157 {
158  const igmp_membership_group_v3_t *igmp_group;
159  igmp_config_t *config;
160  u16 n_groups, ii;
161 
162  config = igmp_config_lookup (args->sw_if_index);
163 
164  if (!config)
165  /*
166  * no IGMP config on the interface. quit
167  */
168  return;
169 
170  if (IGMP_MODE_HOST == config->mode)
171  {
172  /*
173  * Hosts need not listen to the reports of other hosts.
174  * we're done here
175  */
176  return;
177  }
178 
179  /*
180  * we validated this packet when we accepted it in the DP, so
181  * this number is safe to use
182  */
183  n_groups = clib_net_to_host_u16 (args->report[0].n_groups);
184  igmp_group = args->report[0].groups;
185 
186  for (ii = 0; ii < n_groups; ii++)
187  {
188  igmp_handle_group (config, igmp_group);
189 
190  igmp_group = group_cptr (igmp_group,
191  igmp_membership_group_v3_length (igmp_group));
192  }
193 }
194 
195 /*
196  * fd.io coding-style-patch-verification: ON
197  *
198  * Local Variables:
199  * eval: (c-set-style "gnu")
200  * End:
201  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
u8 * format_igmp_src_addr_list(u8 *s, va_list *args)
Definition: igmp_format.c:171
igmp_membership_group_v3_type_t type
Definition: igmp_packet.h:149
u8 * format_igmp_key(u8 *s, va_list *args)
Definition: igmp_format.c:188
void igmp_pkt_query_v3_send(igmp_pkt_build_query_t *bq)
Definition: igmp_pkt.c:516
igmp_membership_group_v3_t groups[0]
Definition: igmp_packet.h:189
igmp_group_t * igmp_group_lookup(igmp_config_t *config, const igmp_key_t *key)
igmp group lookup
Definition: igmp_config.c:76
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static void igmp_handle_group_update(igmp_config_t *config, const igmp_membership_group_v3_t *igmp_group)
Definition: igmp_report.c:50
void igmp_handle_report(const igmp_report_args_t *args)
Definition: igmp_report.c:156
#define NULL
Definition: clib.h:55
igmp_src_t * igmp_group_src_update(igmp_group_t *group, const igmp_key_t *skey, igmp_mode_t mode)
Definition: igmp_group.c:45
void igmp_src_blocked(igmp_src_t *src)
Definition: igmp_src.c:127
format_function_t format_vnet_sw_if_index_name
#define IGMP_DBG(...)
Definition: igmp.h:37
igmp_membership_report_v3_t report[0]
Definition: igmp_report.h:26
static void igmp_handle_group(igmp_config_t *config, const igmp_membership_group_v3_t *igmp_group)
Definition: igmp_report.c:129
igmp_config_t * igmp_config_lookup(u32 sw_if_index)
igmp config lookup
Definition: igmp_config.c:45
unsigned short u16
Definition: types.h:57
igmp_src_t * igmp_src_lookup(igmp_group_t *group, const igmp_key_t *key)
igmp group lookup
Definition: igmp_group.c:240
A copy of the report message sent from the worker to the main thread.
Definition: igmp_report.h:23
igmp_group_t * igmp_group_alloc(igmp_config_t *config, const igmp_key_t *gkey, igmp_filter_mode_t mode)
Definition: igmp_group.c:95
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
void igmp_pkt_query_v3_add_group(igmp_pkt_build_query_t *bq, const igmp_group_t *group, const ip46_address_t *srcs)
Definition: igmp_pkt.c:451
#define group_cptr(p, l)
Definition: igmp.h:57
static ip46_address_t * igmp_group_mk_source_list(const igmp_membership_group_v3_t *r)
Definition: igmp_report.c:22
ip4_address_t group_address
Definition: igmp_packet.h:158
IGMP interface configuration.
Definition: igmp_config.h:43
static u32 igmp_membership_group_v3_length(const igmp_membership_group_v3_t *g)
Definition: igmp_packet.h:164
IGMP group A multicast group address for which reception has been requested.
Definition: igmp_group.h:55
void igmp_pkt_build_query_init(igmp_pkt_build_query_t *bq, u32 sw_if_index)
Definition: igmp_pkt.c:526
ip4_address_t src_addresses[0]
Definition: igmp_packet.h:160
#define vec_foreach(var, vec)
Vector iterator.
igmp_mode_t mode
Definition: igmp_config.h:58
static void igmp_handle_group_block(igmp_config_t *config, const igmp_membership_group_v3_t *igmp_group)
Definition: igmp_report.c:82
IGMP source The representation of a specified source address with in multicast group.
Definition: igmp_src.h:41