1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * IEEE 802.1Q Multiple VLAN Registration Protocol (MVRP) 4 * 5 * Copyright (c) 2012 Massachusetts Institute of Technology 6 * 7 * Adapted from code in net/8021q/vlan_gvrp.c 8 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> 9 */ 10 #include <linux/types.h> 11 #include <linux/if_ether.h> 12 #include <linux/if_vlan.h> 13 #include <net/mrp.h> 14 #include "vlan.h" 15 16 #define MRP_MVRP_ADDRESS { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 } 17 18 enum mvrp_attributes { 19 MVRP_ATTR_INVALID, 20 MVRP_ATTR_VID, 21 __MVRP_ATTR_MAX 22 }; 23 #define MVRP_ATTR_MAX (__MVRP_ATTR_MAX - 1) 24 25 static struct mrp_application vlan_mrp_app __read_mostly = { 26 .type = MRP_APPLICATION_MVRP, 27 .maxattr = MVRP_ATTR_MAX, 28 .pkttype.type = htons(ETH_P_MVRP), 29 .group_address = MRP_MVRP_ADDRESS, 30 .version = 0, 31 }; 32 33 int vlan_mvrp_request_join(const struct net_device *dev) 34 { 35 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 36 __be16 vlan_id = htons(vlan->vlan_id); 37 38 if (vlan->vlan_proto != htons(ETH_P_8021Q)) 39 return 0; 40 return mrp_request_join(vlan->real_dev, &vlan_mrp_app, 41 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); 42 } 43 44 void vlan_mvrp_request_leave(const struct net_device *dev) 45 { 46 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 47 __be16 vlan_id = htons(vlan->vlan_id); 48 49 if (vlan->vlan_proto != htons(ETH_P_8021Q)) 50 return; 51 mrp_request_leave(vlan->real_dev, &vlan_mrp_app, 52 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); 53 } 54 55 int vlan_mvrp_init_applicant(struct net_device *dev) 56 { 57 return mrp_init_applicant(dev, &vlan_mrp_app); 58 } 59 60 void vlan_mvrp_uninit_applicant(struct net_device *dev) 61 { 62 mrp_uninit_applicant(dev, &vlan_mrp_app); 63 } 64 65 int __init vlan_mvrp_init(void) 66 { 67 return mrp_register_application(&vlan_mrp_app); 68 } 69 70 void vlan_mvrp_uninit(void) 71 { 72 mrp_unregister_application(&vlan_mrp_app); 73 } 74