Lines Matching +full:protocol +full:- +full:node

1 // SPDX-License-Identifier: GPL-2.0-only
3 * IEEE 802.1D Generic Attribute Registration Protocol (GARP)
24 MODULE_DESCRIPTION("IEEE 802.1D Generic Attribute Registration Protocol (GARP)");
141 if (attr->type != type) in garp_attr_cmp()
142 return attr->type - type; in garp_attr_cmp()
143 if (attr->dlen != len) in garp_attr_cmp()
144 return attr->dlen - len; in garp_attr_cmp()
145 return memcmp(attr->data, data, len); in garp_attr_cmp()
151 struct rb_node *parent = app->gid.rb_node; in garp_attr_lookup()
156 attr = rb_entry(parent, struct garp_attr, node); in garp_attr_lookup()
159 parent = parent->rb_left; in garp_attr_lookup()
161 parent = parent->rb_right; in garp_attr_lookup()
171 struct rb_node *parent = NULL, **p = &app->gid.rb_node; in garp_attr_create()
177 attr = rb_entry(parent, struct garp_attr, node); in garp_attr_create()
180 p = &parent->rb_left; in garp_attr_create()
182 p = &parent->rb_right; in garp_attr_create()
184 /* The attribute already exists; re-use it. */ in garp_attr_create()
191 attr->state = GARP_APPLICANT_VO; in garp_attr_create()
192 attr->type = type; in garp_attr_create()
193 attr->dlen = len; in garp_attr_create()
194 memcpy(attr->data, data, len); in garp_attr_create()
196 rb_link_node(&attr->node, parent, p); in garp_attr_create()
197 rb_insert_color(&attr->node, &app->gid); in garp_attr_create()
203 rb_erase(&attr->node, &app->gid); in garp_attr_destroy()
209 struct rb_node *node, *next; in garp_attr_destroy_all() local
212 for (node = rb_first(&app->gid); in garp_attr_destroy_all()
213 next = node ? rb_next(node) : NULL, node != NULL; in garp_attr_destroy_all()
214 node = next) { in garp_attr_destroy_all()
215 attr = rb_entry(node, struct garp_attr, node); in garp_attr_destroy_all()
226 skb = alloc_skb(app->dev->mtu + LL_RESERVED_SPACE(app->dev), in garp_pdu_init()
229 return -ENOMEM; in garp_pdu_init()
231 skb->dev = app->dev; in garp_pdu_init()
232 skb->protocol = htons(ETH_P_802_2); in garp_pdu_init()
233 skb_reserve(skb, LL_RESERVED_SPACE(app->dev) + LLC_RESERVE); in garp_pdu_init()
236 put_unaligned(htons(GARP_PROTOCOL_ID), &gp->protocol); in garp_pdu_init()
238 app->pdu = skb; in garp_pdu_init()
244 if (skb_tailroom(app->pdu) < sizeof(u8)) in garp_pdu_append_end_mark()
245 return -1; in garp_pdu_append_end_mark()
246 __skb_put_u8(app->pdu, GARP_END_MARK); in garp_pdu_append_end_mark()
252 if (!app->pdu) in garp_pdu_queue()
258 llc_pdu_header_init(app->pdu, LLC_PDU_TYPE_U, LLC_SAP_BSPAN, in garp_pdu_queue()
260 llc_pdu_init_as_ui_cmd(app->pdu); in garp_pdu_queue()
261 llc_mac_hdr_init(app->pdu, app->dev->dev_addr, in garp_pdu_queue()
262 app->app->proto.group_address); in garp_pdu_queue()
264 skb_queue_tail(&app->queue, app->pdu); in garp_pdu_queue()
265 app->pdu = NULL; in garp_pdu_queue()
272 while ((skb = skb_dequeue(&app->queue))) in garp_queue_xmit()
280 if (skb_tailroom(app->pdu) < sizeof(*gm)) in garp_pdu_append_msg()
281 return -1; in garp_pdu_append_msg()
282 gm = __skb_put(app->pdu, sizeof(*gm)); in garp_pdu_append_msg()
283 gm->attrtype = attrtype; in garp_pdu_append_msg()
284 garp_cb(app->pdu)->cur_type = attrtype; in garp_pdu_append_msg()
296 if (!app->pdu) { in garp_pdu_append_attr()
302 if (garp_cb(app->pdu)->cur_type != attr->type) { in garp_pdu_append_attr()
303 if (garp_cb(app->pdu)->cur_type && in garp_pdu_append_attr()
306 if (garp_pdu_append_msg(app, attr->type) < 0) in garp_pdu_append_attr()
310 len = sizeof(*ga) + attr->dlen; in garp_pdu_append_attr()
311 if (skb_tailroom(app->pdu) < len) in garp_pdu_append_attr()
313 ga = __skb_put(app->pdu, len); in garp_pdu_append_attr()
314 ga->len = len; in garp_pdu_append_attr()
315 ga->event = event; in garp_pdu_append_attr()
316 memcpy(ga->data, attr->data, attr->dlen); in garp_pdu_append_attr()
329 state = garp_applicant_state_table[attr->state][event].state; in garp_attr_event()
333 switch (garp_applicant_state_table[attr->state][event].action) { in garp_attr_event()
352 attr->state = state; in garp_attr_event()
359 struct garp_port *port = rtnl_dereference(dev->garp_port); in garp_request_join()
360 struct garp_applicant *app = rtnl_dereference(port->applicants[appl->type]); in garp_request_join()
363 spin_lock_bh(&app->lock); in garp_request_join()
366 spin_unlock_bh(&app->lock); in garp_request_join()
367 return -ENOMEM; in garp_request_join()
370 spin_unlock_bh(&app->lock); in garp_request_join()
379 struct garp_port *port = rtnl_dereference(dev->garp_port); in garp_request_leave()
380 struct garp_applicant *app = rtnl_dereference(port->applicants[appl->type]); in garp_request_leave()
383 spin_lock_bh(&app->lock); in garp_request_leave()
386 spin_unlock_bh(&app->lock); in garp_request_leave()
390 spin_unlock_bh(&app->lock); in garp_request_leave()
396 struct rb_node *node, *next; in garp_gid_event() local
399 for (node = rb_first(&app->gid); in garp_gid_event()
400 next = node ? rb_next(node) : NULL, node != NULL; in garp_gid_event()
401 node = next) { in garp_gid_event()
402 attr = rb_entry(node, struct garp_attr, node); in garp_gid_event()
412 mod_timer(&app->join_timer, jiffies + delay); in garp_join_timer_arm()
419 spin_lock(&app->lock); in garp_join_timer()
422 spin_unlock(&app->lock); in garp_join_timer()
431 return -1; in garp_pdu_parse_end_mark()
432 if (*skb->data == GARP_END_MARK) { in garp_pdu_parse_end_mark()
434 return -1; in garp_pdu_parse_end_mark()
448 return -1; in garp_pdu_parse_attr()
449 ga = (struct garp_attr_hdr *)skb->data; in garp_pdu_parse_attr()
450 if (ga->len < sizeof(*ga)) in garp_pdu_parse_attr()
451 return -1; in garp_pdu_parse_attr()
453 if (!pskb_may_pull(skb, ga->len)) in garp_pdu_parse_attr()
454 return -1; in garp_pdu_parse_attr()
455 skb_pull(skb, ga->len); in garp_pdu_parse_attr()
456 dlen = sizeof(*ga) - ga->len; in garp_pdu_parse_attr()
458 if (attrtype > app->app->maxattr) in garp_pdu_parse_attr()
461 switch (ga->event) { in garp_pdu_parse_attr()
464 return -1; in garp_pdu_parse_attr()
484 return -1; in garp_pdu_parse_attr()
485 attr = garp_attr_lookup(app, ga->data, dlen, attrtype); in garp_pdu_parse_attr()
497 return -1; in garp_pdu_parse_msg()
498 gm = (struct garp_msg_hdr *)skb->data; in garp_pdu_parse_msg()
499 if (gm->attrtype == 0) in garp_pdu_parse_msg()
500 return -1; in garp_pdu_parse_msg()
503 while (skb->len > 0) { in garp_pdu_parse_msg()
504 if (garp_pdu_parse_attr(app, skb, gm->attrtype) < 0) in garp_pdu_parse_msg()
505 return -1; in garp_pdu_parse_msg()
515 struct garp_application *appl = proto->data; in garp_pdu_rcv()
520 port = rcu_dereference(dev->garp_port); in garp_pdu_rcv()
523 app = rcu_dereference(port->applicants[appl->type]); in garp_pdu_rcv()
529 gp = (struct garp_pdu_hdr *)skb->data; in garp_pdu_rcv()
530 if (get_unaligned(&gp->protocol) != htons(GARP_PROTOCOL_ID)) in garp_pdu_rcv()
534 spin_lock(&app->lock); in garp_pdu_rcv()
535 while (skb->len > 0) { in garp_pdu_rcv()
541 spin_unlock(&app->lock); in garp_pdu_rcv()
552 return -ENOMEM; in garp_init_port()
553 rcu_assign_pointer(dev->garp_port, port); in garp_init_port()
559 struct garp_port *port = rtnl_dereference(dev->garp_port); in garp_release_port()
563 if (rtnl_dereference(port->applicants[i])) in garp_release_port()
566 RCU_INIT_POINTER(dev->garp_port, NULL); in garp_release_port()
577 if (!rtnl_dereference(dev->garp_port)) { in garp_init_applicant()
583 err = -ENOMEM; in garp_init_applicant()
588 err = dev_mc_add(dev, appl->proto.group_address); in garp_init_applicant()
592 app->dev = dev; in garp_init_applicant()
593 app->app = appl; in garp_init_applicant()
594 app->gid = RB_ROOT; in garp_init_applicant()
595 spin_lock_init(&app->lock); in garp_init_applicant()
596 skb_queue_head_init(&app->queue); in garp_init_applicant()
597 rcu_assign_pointer(dev->garp_port->applicants[appl->type], app); in garp_init_applicant()
598 timer_setup(&app->join_timer, garp_join_timer, 0); in garp_init_applicant()
613 struct garp_port *port = rtnl_dereference(dev->garp_port); in garp_uninit_applicant()
614 struct garp_applicant *app = rtnl_dereference(port->applicants[appl->type]); in garp_uninit_applicant()
618 RCU_INIT_POINTER(port->applicants[appl->type], NULL); in garp_uninit_applicant()
622 timer_shutdown_sync(&app->join_timer); in garp_uninit_applicant()
624 spin_lock_bh(&app->lock); in garp_uninit_applicant()
628 spin_unlock_bh(&app->lock); in garp_uninit_applicant()
632 dev_mc_del(dev, appl->proto.group_address); in garp_uninit_applicant()
640 appl->proto.rcv = garp_pdu_rcv; in garp_register_application()
641 appl->proto.data = appl; in garp_register_application()
642 return stp_proto_register(&appl->proto); in garp_register_application()
648 stp_proto_unregister(&appl->proto); in garp_unregister_application()