~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/bridge/br_cfm_netlink.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 
  3 #include <net/genetlink.h>
  4 
  5 #include "br_private.h"
  6 #include "br_private_cfm.h"
  7 
  8 static const struct nla_policy
  9 br_cfm_mep_create_policy[IFLA_BRIDGE_CFM_MEP_CREATE_MAX + 1] = {
 10         [IFLA_BRIDGE_CFM_MEP_CREATE_UNSPEC]     = { .type = NLA_REJECT },
 11         [IFLA_BRIDGE_CFM_MEP_CREATE_INSTANCE]   = { .type = NLA_U32 },
 12         [IFLA_BRIDGE_CFM_MEP_CREATE_DOMAIN]     = { .type = NLA_U32 },
 13         [IFLA_BRIDGE_CFM_MEP_CREATE_DIRECTION]  = { .type = NLA_U32 },
 14         [IFLA_BRIDGE_CFM_MEP_CREATE_IFINDEX]    = { .type = NLA_U32 },
 15 };
 16 
 17 static const struct nla_policy
 18 br_cfm_mep_delete_policy[IFLA_BRIDGE_CFM_MEP_DELETE_MAX + 1] = {
 19         [IFLA_BRIDGE_CFM_MEP_DELETE_UNSPEC]     = { .type = NLA_REJECT },
 20         [IFLA_BRIDGE_CFM_MEP_DELETE_INSTANCE]   = { .type = NLA_U32 },
 21 };
 22 
 23 static const struct nla_policy
 24 br_cfm_mep_config_policy[IFLA_BRIDGE_CFM_MEP_CONFIG_MAX + 1] = {
 25         [IFLA_BRIDGE_CFM_MEP_CONFIG_UNSPEC]      = { .type = NLA_REJECT },
 26         [IFLA_BRIDGE_CFM_MEP_CONFIG_INSTANCE]    = { .type = NLA_U32 },
 27         [IFLA_BRIDGE_CFM_MEP_CONFIG_UNICAST_MAC] = NLA_POLICY_ETH_ADDR,
 28         [IFLA_BRIDGE_CFM_MEP_CONFIG_MDLEVEL]     = NLA_POLICY_MAX(NLA_U32, 7),
 29         [IFLA_BRIDGE_CFM_MEP_CONFIG_MEPID]       = NLA_POLICY_MAX(NLA_U32, 0x1FFF),
 30 };
 31 
 32 static const struct nla_policy
 33 br_cfm_cc_config_policy[IFLA_BRIDGE_CFM_CC_CONFIG_MAX + 1] = {
 34         [IFLA_BRIDGE_CFM_CC_CONFIG_UNSPEC]       = { .type = NLA_REJECT },
 35         [IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE]     = { .type = NLA_U32 },
 36         [IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE]       = { .type = NLA_U32 },
 37         [IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL] = { .type = NLA_U32 },
 38         [IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID]     = {
 39         .type = NLA_BINARY, .len = CFM_MAID_LENGTH },
 40 };
 41 
 42 static const struct nla_policy
 43 br_cfm_cc_peer_mep_policy[IFLA_BRIDGE_CFM_CC_PEER_MEP_MAX + 1] = {
 44         [IFLA_BRIDGE_CFM_CC_PEER_MEP_UNSPEC]    = { .type = NLA_REJECT },
 45         [IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE]  = { .type = NLA_U32 },
 46         [IFLA_BRIDGE_CFM_CC_PEER_MEPID]         = NLA_POLICY_MAX(NLA_U32, 0x1FFF),
 47 };
 48 
 49 static const struct nla_policy
 50 br_cfm_cc_rdi_policy[IFLA_BRIDGE_CFM_CC_RDI_MAX + 1] = {
 51         [IFLA_BRIDGE_CFM_CC_RDI_UNSPEC]         = { .type = NLA_REJECT },
 52         [IFLA_BRIDGE_CFM_CC_RDI_INSTANCE]       = { .type = NLA_U32 },
 53         [IFLA_BRIDGE_CFM_CC_RDI_RDI]            = { .type = NLA_U32 },
 54 };
 55 
 56 static const struct nla_policy
 57 br_cfm_cc_ccm_tx_policy[IFLA_BRIDGE_CFM_CC_CCM_TX_MAX + 1] = {
 58         [IFLA_BRIDGE_CFM_CC_CCM_TX_UNSPEC]         = { .type = NLA_REJECT },
 59         [IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE]       = { .type = NLA_U32 },
 60         [IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC]           = NLA_POLICY_ETH_ADDR,
 61         [IFLA_BRIDGE_CFM_CC_CCM_TX_SEQ_NO_UPDATE]  = { .type = NLA_U32 },
 62         [IFLA_BRIDGE_CFM_CC_CCM_TX_PERIOD]         = { .type = NLA_U32 },
 63         [IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV]         = { .type = NLA_U32 },
 64         [IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV_VALUE]   = { .type = NLA_U8 },
 65         [IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV]       = { .type = NLA_U32 },
 66         [IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV_VALUE] = { .type = NLA_U8 },
 67 };
 68 
 69 static const struct nla_policy
 70 br_cfm_policy[IFLA_BRIDGE_CFM_MAX + 1] = {
 71         [IFLA_BRIDGE_CFM_UNSPEC]                = { .type = NLA_REJECT },
 72         [IFLA_BRIDGE_CFM_MEP_CREATE]            =
 73                                 NLA_POLICY_NESTED(br_cfm_mep_create_policy),
 74         [IFLA_BRIDGE_CFM_MEP_DELETE]            =
 75                                 NLA_POLICY_NESTED(br_cfm_mep_delete_policy),
 76         [IFLA_BRIDGE_CFM_MEP_CONFIG]            =
 77                                 NLA_POLICY_NESTED(br_cfm_mep_config_policy),
 78         [IFLA_BRIDGE_CFM_CC_CONFIG]             =
 79                                 NLA_POLICY_NESTED(br_cfm_cc_config_policy),
 80         [IFLA_BRIDGE_CFM_CC_PEER_MEP_ADD]       =
 81                                 NLA_POLICY_NESTED(br_cfm_cc_peer_mep_policy),
 82         [IFLA_BRIDGE_CFM_CC_PEER_MEP_REMOVE]    =
 83                                 NLA_POLICY_NESTED(br_cfm_cc_peer_mep_policy),
 84         [IFLA_BRIDGE_CFM_CC_RDI]                =
 85                                 NLA_POLICY_NESTED(br_cfm_cc_rdi_policy),
 86         [IFLA_BRIDGE_CFM_CC_CCM_TX]             =
 87                                 NLA_POLICY_NESTED(br_cfm_cc_ccm_tx_policy),
 88 };
 89 
 90 static int br_mep_create_parse(struct net_bridge *br, struct nlattr *attr,
 91                                struct netlink_ext_ack *extack)
 92 {
 93         struct nlattr *tb[IFLA_BRIDGE_CFM_MEP_CREATE_MAX + 1];
 94         struct br_cfm_mep_create create;
 95         u32 instance;
 96         int err;
 97 
 98         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_MEP_CREATE_MAX, attr,
 99                                br_cfm_mep_create_policy, extack);
100         if (err)
101                 return err;
102 
103         if (!tb[IFLA_BRIDGE_CFM_MEP_CREATE_INSTANCE]) {
104                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
105                 return -EINVAL;
106         }
107         if (!tb[IFLA_BRIDGE_CFM_MEP_CREATE_DOMAIN]) {
108                 NL_SET_ERR_MSG_MOD(extack, "Missing DOMAIN attribute");
109                 return -EINVAL;
110         }
111         if (!tb[IFLA_BRIDGE_CFM_MEP_CREATE_DIRECTION]) {
112                 NL_SET_ERR_MSG_MOD(extack, "Missing DIRECTION attribute");
113                 return -EINVAL;
114         }
115         if (!tb[IFLA_BRIDGE_CFM_MEP_CREATE_IFINDEX]) {
116                 NL_SET_ERR_MSG_MOD(extack, "Missing IFINDEX attribute");
117                 return -EINVAL;
118         }
119 
120         memset(&create, 0, sizeof(create));
121 
122         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CREATE_INSTANCE]);
123         create.domain = nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CREATE_DOMAIN]);
124         create.direction = nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CREATE_DIRECTION]);
125         create.ifindex = nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CREATE_IFINDEX]);
126 
127         return br_cfm_mep_create(br, instance, &create, extack);
128 }
129 
130 static int br_mep_delete_parse(struct net_bridge *br, struct nlattr *attr,
131                                struct netlink_ext_ack *extack)
132 {
133         struct nlattr *tb[IFLA_BRIDGE_CFM_MEP_DELETE_MAX + 1];
134         u32 instance;
135         int err;
136 
137         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_MEP_DELETE_MAX, attr,
138                                br_cfm_mep_delete_policy, extack);
139         if (err)
140                 return err;
141 
142         if (!tb[IFLA_BRIDGE_CFM_MEP_DELETE_INSTANCE]) {
143                 NL_SET_ERR_MSG_MOD(extack,
144                                    "Missing INSTANCE attribute");
145                 return -EINVAL;
146         }
147 
148         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_DELETE_INSTANCE]);
149 
150         return br_cfm_mep_delete(br, instance, extack);
151 }
152 
153 static int br_mep_config_parse(struct net_bridge *br, struct nlattr *attr,
154                                struct netlink_ext_ack *extack)
155 {
156         struct nlattr *tb[IFLA_BRIDGE_CFM_MEP_CONFIG_MAX + 1];
157         struct br_cfm_mep_config config;
158         u32 instance;
159         int err;
160 
161         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_MEP_CONFIG_MAX, attr,
162                                br_cfm_mep_config_policy, extack);
163         if (err)
164                 return err;
165 
166         if (!tb[IFLA_BRIDGE_CFM_MEP_CONFIG_INSTANCE]) {
167                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
168                 return -EINVAL;
169         }
170         if (!tb[IFLA_BRIDGE_CFM_MEP_CONFIG_UNICAST_MAC]) {
171                 NL_SET_ERR_MSG_MOD(extack, "Missing UNICAST_MAC attribute");
172                 return -EINVAL;
173         }
174         if (!tb[IFLA_BRIDGE_CFM_MEP_CONFIG_MDLEVEL]) {
175                 NL_SET_ERR_MSG_MOD(extack, "Missing MDLEVEL attribute");
176                 return -EINVAL;
177         }
178         if (!tb[IFLA_BRIDGE_CFM_MEP_CONFIG_MEPID]) {
179                 NL_SET_ERR_MSG_MOD(extack, "Missing MEPID attribute");
180                 return -EINVAL;
181         }
182 
183         memset(&config, 0, sizeof(config));
184 
185         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CONFIG_INSTANCE]);
186         nla_memcpy(&config.unicast_mac.addr,
187                    tb[IFLA_BRIDGE_CFM_MEP_CONFIG_UNICAST_MAC],
188                    sizeof(config.unicast_mac.addr));
189         config.mdlevel = nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CONFIG_MDLEVEL]);
190         config.mepid = nla_get_u32(tb[IFLA_BRIDGE_CFM_MEP_CONFIG_MEPID]);
191 
192         return br_cfm_mep_config_set(br, instance, &config, extack);
193 }
194 
195 static int br_cc_config_parse(struct net_bridge *br, struct nlattr *attr,
196                               struct netlink_ext_ack *extack)
197 {
198         struct nlattr *tb[IFLA_BRIDGE_CFM_CC_CONFIG_MAX + 1];
199         struct br_cfm_cc_config config;
200         u32 instance;
201         int err;
202 
203         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_CC_CONFIG_MAX, attr,
204                                br_cfm_cc_config_policy, extack);
205         if (err)
206                 return err;
207 
208         if (!tb[IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE]) {
209                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
210                 return -EINVAL;
211         }
212         if (!tb[IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE]) {
213                 NL_SET_ERR_MSG_MOD(extack, "Missing ENABLE attribute");
214                 return -EINVAL;
215         }
216         if (!tb[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL]) {
217                 NL_SET_ERR_MSG_MOD(extack, "Missing INTERVAL attribute");
218                 return -EINVAL;
219         }
220         if (!tb[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID]) {
221                 NL_SET_ERR_MSG_MOD(extack, "Missing MAID attribute");
222                 return -EINVAL;
223         }
224 
225         memset(&config, 0, sizeof(config));
226 
227         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE]);
228         config.enable = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE]);
229         config.exp_interval = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL]);
230         nla_memcpy(&config.exp_maid.data, tb[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID],
231                    sizeof(config.exp_maid.data));
232 
233         return br_cfm_cc_config_set(br, instance, &config, extack);
234 }
235 
236 static int br_cc_peer_mep_add_parse(struct net_bridge *br, struct nlattr *attr,
237                                     struct netlink_ext_ack *extack)
238 {
239         struct nlattr *tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_MAX + 1];
240         u32 instance, peer_mep_id;
241         int err;
242 
243         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_CC_PEER_MEP_MAX, attr,
244                                br_cfm_cc_peer_mep_policy, extack);
245         if (err)
246                 return err;
247 
248         if (!tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE]) {
249                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
250                 return -EINVAL;
251         }
252         if (!tb[IFLA_BRIDGE_CFM_CC_PEER_MEPID]) {
253                 NL_SET_ERR_MSG_MOD(extack, "Missing PEER_MEP_ID attribute");
254                 return -EINVAL;
255         }
256 
257         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE]);
258         peer_mep_id =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_PEER_MEPID]);
259 
260         return br_cfm_cc_peer_mep_add(br, instance, peer_mep_id, extack);
261 }
262 
263 static int br_cc_peer_mep_remove_parse(struct net_bridge *br, struct nlattr *attr,
264                                        struct netlink_ext_ack *extack)
265 {
266         struct nlattr *tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_MAX + 1];
267         u32 instance, peer_mep_id;
268         int err;
269 
270         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_CC_PEER_MEP_MAX, attr,
271                                br_cfm_cc_peer_mep_policy, extack);
272         if (err)
273                 return err;
274 
275         if (!tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE]) {
276                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
277                 return -EINVAL;
278         }
279         if (!tb[IFLA_BRIDGE_CFM_CC_PEER_MEPID]) {
280                 NL_SET_ERR_MSG_MOD(extack, "Missing PEER_MEP_ID attribute");
281                 return -EINVAL;
282         }
283 
284         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE]);
285         peer_mep_id =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_PEER_MEPID]);
286 
287         return br_cfm_cc_peer_mep_remove(br, instance, peer_mep_id, extack);
288 }
289 
290 static int br_cc_rdi_parse(struct net_bridge *br, struct nlattr *attr,
291                            struct netlink_ext_ack *extack)
292 {
293         struct nlattr *tb[IFLA_BRIDGE_CFM_CC_RDI_MAX + 1];
294         u32 instance, rdi;
295         int err;
296 
297         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_CC_RDI_MAX, attr,
298                                br_cfm_cc_rdi_policy, extack);
299         if (err)
300                 return err;
301 
302         if (!tb[IFLA_BRIDGE_CFM_CC_RDI_INSTANCE]) {
303                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
304                 return -EINVAL;
305         }
306         if (!tb[IFLA_BRIDGE_CFM_CC_RDI_RDI]) {
307                 NL_SET_ERR_MSG_MOD(extack, "Missing RDI attribute");
308                 return -EINVAL;
309         }
310 
311         instance =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_RDI_INSTANCE]);
312         rdi =  nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_RDI_RDI]);
313 
314         return br_cfm_cc_rdi_set(br, instance, rdi, extack);
315 }
316 
317 static int br_cc_ccm_tx_parse(struct net_bridge *br, struct nlattr *attr,
318                               struct netlink_ext_ack *extack)
319 {
320         struct nlattr *tb[IFLA_BRIDGE_CFM_CC_CCM_TX_MAX + 1];
321         struct br_cfm_cc_ccm_tx_info tx_info;
322         u32 instance;
323         int err;
324 
325         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_CC_CCM_TX_MAX, attr,
326                                br_cfm_cc_ccm_tx_policy, extack);
327         if (err)
328                 return err;
329 
330         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE]) {
331                 NL_SET_ERR_MSG_MOD(extack, "Missing INSTANCE attribute");
332                 return -EINVAL;
333         }
334         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC]) {
335                 NL_SET_ERR_MSG_MOD(extack, "Missing DMAC attribute");
336                 return -EINVAL;
337         }
338         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_SEQ_NO_UPDATE]) {
339                 NL_SET_ERR_MSG_MOD(extack, "Missing SEQ_NO_UPDATE attribute");
340                 return -EINVAL;
341         }
342         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PERIOD]) {
343                 NL_SET_ERR_MSG_MOD(extack, "Missing PERIOD attribute");
344                 return -EINVAL;
345         }
346         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV]) {
347                 NL_SET_ERR_MSG_MOD(extack, "Missing IF_TLV attribute");
348                 return -EINVAL;
349         }
350         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV_VALUE]) {
351                 NL_SET_ERR_MSG_MOD(extack, "Missing IF_TLV_VALUE attribute");
352                 return -EINVAL;
353         }
354         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV]) {
355                 NL_SET_ERR_MSG_MOD(extack, "Missing PORT_TLV attribute");
356                 return -EINVAL;
357         }
358         if (!tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV_VALUE]) {
359                 NL_SET_ERR_MSG_MOD(extack, "Missing PORT_TLV_VALUE attribute");
360                 return -EINVAL;
361         }
362 
363         memset(&tx_info, 0, sizeof(tx_info));
364 
365         instance = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE]);
366         nla_memcpy(&tx_info.dmac.addr,
367                    tb[IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC],
368                    sizeof(tx_info.dmac.addr));
369         tx_info.seq_no_update = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_SEQ_NO_UPDATE]);
370         tx_info.period = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PERIOD]);
371         tx_info.if_tlv = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV]);
372         tx_info.if_tlv_value = nla_get_u8(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV_VALUE]);
373         tx_info.port_tlv = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV]);
374         tx_info.port_tlv_value = nla_get_u8(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV_VALUE]);
375 
376         return br_cfm_cc_ccm_tx(br, instance, &tx_info, extack);
377 }
378 
379 int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
380                  struct nlattr *attr, int cmd, struct netlink_ext_ack *extack)
381 {
382         struct nlattr *tb[IFLA_BRIDGE_CFM_MAX + 1];
383         int err;
384 
385         /* When this function is called for a port then the br pointer is
386          * invalid, therefor set the br to point correctly
387          */
388         if (p)
389                 br = p->br;
390 
391         err = nla_parse_nested(tb, IFLA_BRIDGE_CFM_MAX, attr,
392                                br_cfm_policy, extack);
393         if (err)
394                 return err;
395 
396         if (tb[IFLA_BRIDGE_CFM_MEP_CREATE]) {
397                 err = br_mep_create_parse(br, tb[IFLA_BRIDGE_CFM_MEP_CREATE],
398                                           extack);
399                 if (err)
400                         return err;
401         }
402 
403         if (tb[IFLA_BRIDGE_CFM_MEP_DELETE]) {
404                 err = br_mep_delete_parse(br, tb[IFLA_BRIDGE_CFM_MEP_DELETE],
405                                           extack);
406                 if (err)
407                         return err;
408         }
409 
410         if (tb[IFLA_BRIDGE_CFM_MEP_CONFIG]) {
411                 err = br_mep_config_parse(br, tb[IFLA_BRIDGE_CFM_MEP_CONFIG],
412                                           extack);
413                 if (err)
414                         return err;
415         }
416 
417         if (tb[IFLA_BRIDGE_CFM_CC_CONFIG]) {
418                 err = br_cc_config_parse(br, tb[IFLA_BRIDGE_CFM_CC_CONFIG],
419                                          extack);
420                 if (err)
421                         return err;
422         }
423 
424         if (tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_ADD]) {
425                 err = br_cc_peer_mep_add_parse(br, tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_ADD],
426                                                extack);
427                 if (err)
428                         return err;
429         }
430 
431         if (tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_REMOVE]) {
432                 err = br_cc_peer_mep_remove_parse(br, tb[IFLA_BRIDGE_CFM_CC_PEER_MEP_REMOVE],
433                                                   extack);
434                 if (err)
435                         return err;
436         }
437 
438         if (tb[IFLA_BRIDGE_CFM_CC_RDI]) {
439                 err = br_cc_rdi_parse(br, tb[IFLA_BRIDGE_CFM_CC_RDI],
440                                       extack);
441                 if (err)
442                         return err;
443         }
444 
445         if (tb[IFLA_BRIDGE_CFM_CC_CCM_TX]) {
446                 err = br_cc_ccm_tx_parse(br, tb[IFLA_BRIDGE_CFM_CC_CCM_TX],
447                                          extack);
448                 if (err)
449                         return err;
450         }
451 
452         return 0;
453 }
454 
455 int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
456 {
457         struct br_cfm_peer_mep *peer_mep;
458         struct br_cfm_mep *mep;
459         struct nlattr *tb;
460 
461         hlist_for_each_entry_rcu(mep, &br->mep_list, head) {
462                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_MEP_CREATE_INFO);
463                 if (!tb)
464                         goto nla_info_failure;
465 
466                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CREATE_INSTANCE,
467                                 mep->instance))
468                         goto nla_put_failure;
469 
470                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CREATE_DOMAIN,
471                                 mep->create.domain))
472                         goto nla_put_failure;
473 
474                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CREATE_DIRECTION,
475                                 mep->create.direction))
476                         goto nla_put_failure;
477 
478                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CREATE_IFINDEX,
479                                 mep->create.ifindex))
480                         goto nla_put_failure;
481 
482                 nla_nest_end(skb, tb);
483 
484                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_MEP_CONFIG_INFO);
485 
486                 if (!tb)
487                         goto nla_info_failure;
488 
489                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CONFIG_INSTANCE,
490                                 mep->instance))
491                         goto nla_put_failure;
492 
493                 if (nla_put(skb, IFLA_BRIDGE_CFM_MEP_CONFIG_UNICAST_MAC,
494                             sizeof(mep->config.unicast_mac.addr),
495                             mep->config.unicast_mac.addr))
496                         goto nla_put_failure;
497 
498                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CONFIG_MDLEVEL,
499                                 mep->config.mdlevel))
500                         goto nla_put_failure;
501 
502                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_CONFIG_MEPID,
503                                 mep->config.mepid))
504                         goto nla_put_failure;
505 
506                 nla_nest_end(skb, tb);
507 
508                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_CC_CONFIG_INFO);
509 
510                 if (!tb)
511                         goto nla_info_failure;
512 
513                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE,
514                                 mep->instance))
515                         goto nla_put_failure;
516 
517                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE,
518                                 mep->cc_config.enable))
519                         goto nla_put_failure;
520 
521                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL,
522                                 mep->cc_config.exp_interval))
523                         goto nla_put_failure;
524 
525                 if (nla_put(skb, IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID,
526                             sizeof(mep->cc_config.exp_maid.data),
527                             mep->cc_config.exp_maid.data))
528                         goto nla_put_failure;
529 
530                 nla_nest_end(skb, tb);
531 
532                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_CC_RDI_INFO);
533 
534                 if (!tb)
535                         goto nla_info_failure;
536 
537                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_RDI_INSTANCE,
538                                 mep->instance))
539                         goto nla_put_failure;
540 
541                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_RDI_RDI,
542                                 mep->rdi))
543                         goto nla_put_failure;
544 
545                 nla_nest_end(skb, tb);
546 
547                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_INFO);
548 
549                 if (!tb)
550                         goto nla_info_failure;
551 
552                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE,
553                                 mep->instance))
554                         goto nla_put_failure;
555 
556                 if (nla_put(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC,
557                             sizeof(mep->cc_ccm_tx_info.dmac),
558                             mep->cc_ccm_tx_info.dmac.addr))
559                         goto nla_put_failure;
560 
561                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_SEQ_NO_UPDATE,
562                                 mep->cc_ccm_tx_info.seq_no_update))
563                         goto nla_put_failure;
564 
565                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_PERIOD,
566                                 mep->cc_ccm_tx_info.period))
567                         goto nla_put_failure;
568 
569                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV,
570                                 mep->cc_ccm_tx_info.if_tlv))
571                         goto nla_put_failure;
572 
573                 if (nla_put_u8(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV_VALUE,
574                                mep->cc_ccm_tx_info.if_tlv_value))
575                         goto nla_put_failure;
576 
577                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV,
578                                 mep->cc_ccm_tx_info.port_tlv))
579                         goto nla_put_failure;
580 
581                 if (nla_put_u8(skb, IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV_VALUE,
582                                mep->cc_ccm_tx_info.port_tlv_value))
583                         goto nla_put_failure;
584 
585                 nla_nest_end(skb, tb);
586 
587                 hlist_for_each_entry_rcu(peer_mep, &mep->peer_mep_list, head) {
588                         tb = nla_nest_start(skb,
589                                             IFLA_BRIDGE_CFM_CC_PEER_MEP_INFO);
590 
591                         if (!tb)
592                                 goto nla_info_failure;
593 
594                         if (nla_put_u32(skb,
595                                         IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE,
596                                         mep->instance))
597                                 goto nla_put_failure;
598 
599                         if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_PEER_MEPID,
600                                         peer_mep->mepid))
601                                 goto nla_put_failure;
602 
603                         nla_nest_end(skb, tb);
604                 }
605         }
606 
607         return 0;
608 
609 nla_put_failure:
610         nla_nest_cancel(skb, tb);
611 
612 nla_info_failure:
613         return -EMSGSIZE;
614 }
615 
616 int br_cfm_status_fill_info(struct sk_buff *skb,
617                             struct net_bridge *br,
618                             bool getlink)
619 {
620         struct br_cfm_peer_mep *peer_mep;
621         struct br_cfm_mep *mep;
622         struct nlattr *tb;
623 
624         hlist_for_each_entry_rcu(mep, &br->mep_list, head) {
625                 tb = nla_nest_start(skb, IFLA_BRIDGE_CFM_MEP_STATUS_INFO);
626                 if (!tb)
627                         goto nla_info_failure;
628 
629                 if (nla_put_u32(skb, IFLA_BRIDGE_CFM_MEP_STATUS_INSTANCE,
630                                 mep->instance))
631                         goto nla_put_failure;
632 
633                 if (nla_put_u32(skb,
634                                 IFLA_BRIDGE_CFM_MEP_STATUS_OPCODE_UNEXP_SEEN,
635                                 mep->status.opcode_unexp_seen))
636                         goto nla_put_failure;
637 
638                 if (nla_put_u32(skb,
639                                 IFLA_BRIDGE_CFM_MEP_STATUS_VERSION_UNEXP_SEEN,
640                                 mep->status.version_unexp_seen))
641                         goto nla_put_failure;
642 
643                 if (nla_put_u32(skb,
644                                 IFLA_BRIDGE_CFM_MEP_STATUS_RX_LEVEL_LOW_SEEN,
645                                 mep->status.rx_level_low_seen))
646                         goto nla_put_failure;
647 
648                 /* Only clear if this is a GETLINK */
649                 if (getlink) {
650                         /* Clear all 'seen' indications */
651                         mep->status.opcode_unexp_seen = false;
652                         mep->status.version_unexp_seen = false;
653                         mep->status.rx_level_low_seen = false;
654                 }
655 
656                 nla_nest_end(skb, tb);
657 
658                 hlist_for_each_entry_rcu(peer_mep, &mep->peer_mep_list, head) {
659                         tb = nla_nest_start(skb,
660                                             IFLA_BRIDGE_CFM_CC_PEER_STATUS_INFO);
661                         if (!tb)
662                                 goto nla_info_failure;
663 
664                         if (nla_put_u32(skb,
665                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_INSTANCE,
666                                         mep->instance))
667                                 goto nla_put_failure;
668 
669                         if (nla_put_u32(skb,
670                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_PEER_MEPID,
671                                         peer_mep->mepid))
672                                 goto nla_put_failure;
673 
674                         if (nla_put_u32(skb,
675                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_CCM_DEFECT,
676                                         peer_mep->cc_status.ccm_defect))
677                                 goto nla_put_failure;
678 
679                         if (nla_put_u32(skb, IFLA_BRIDGE_CFM_CC_PEER_STATUS_RDI,
680                                         peer_mep->cc_status.rdi))
681                                 goto nla_put_failure;
682 
683                         if (nla_put_u8(skb,
684                                        IFLA_BRIDGE_CFM_CC_PEER_STATUS_PORT_TLV_VALUE,
685                                        peer_mep->cc_status.port_tlv_value))
686                                 goto nla_put_failure;
687 
688                         if (nla_put_u8(skb,
689                                        IFLA_BRIDGE_CFM_CC_PEER_STATUS_IF_TLV_VALUE,
690                                        peer_mep->cc_status.if_tlv_value))
691                                 goto nla_put_failure;
692 
693                         if (nla_put_u32(skb,
694                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_SEEN,
695                                         peer_mep->cc_status.seen))
696                                 goto nla_put_failure;
697 
698                         if (nla_put_u32(skb,
699                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_TLV_SEEN,
700                                         peer_mep->cc_status.tlv_seen))
701                                 goto nla_put_failure;
702 
703                         if (nla_put_u32(skb,
704                                         IFLA_BRIDGE_CFM_CC_PEER_STATUS_SEQ_UNEXP_SEEN,
705                                         peer_mep->cc_status.seq_unexp_seen))
706                                 goto nla_put_failure;
707 
708                         if (getlink) { /* Only clear if this is a GETLINK */
709                                 /* Clear all 'seen' indications */
710                                 peer_mep->cc_status.seen = false;
711                                 peer_mep->cc_status.tlv_seen = false;
712                                 peer_mep->cc_status.seq_unexp_seen = false;
713                         }
714 
715                         nla_nest_end(skb, tb);
716                 }
717         }
718 
719         return 0;
720 
721 nla_put_failure:
722         nla_nest_cancel(skb, tb);
723 
724 nla_info_failure:
725         return -EMSGSIZE;
726 }
727 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php