1 /* 2 * Bridge netlink control interface 3 * 4 * Authors: 5 * Stephen Hemminger <shemminger@osdl.org> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 */ 12 13 #include <linux/kernel.h> 14 #include <net/rtnetlink.h> 15 #include <net/net_namespace.h> 16 #include "br_private.h" 17 18 static inline size_t br_nlmsg_size(void) 19 { 20 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 21 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 22 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ 23 + nla_total_size(4) /* IFLA_MASTER */ 24 + nla_total_size(4) /* IFLA_MTU */ 25 + nla_total_size(4) /* IFLA_LINK */ 26 + nla_total_size(1) /* IFLA_OPERSTATE */ 27 + nla_total_size(1); /* IFLA_PROTINFO */ 28 } 29 30 /* 31 * Create one netlink message for one interface 32 * Contains port and master info as well as carrier and bridge state. 33 */ 34 static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port, 35 u32 pid, u32 seq, int event, unsigned int flags) 36 { 37 const struct net_bridge *br = port->br; 38 const struct net_device *dev = port->dev; 39 struct ifinfomsg *hdr; 40 struct nlmsghdr *nlh; 41 u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; 42 43 pr_debug("br_fill_info event %d port %s master %s\n", 44 event, dev->name, br->dev->name); 45 46 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 47 if (nlh == NULL) 48 return -EMSGSIZE; 49 50 hdr = nlmsg_data(nlh); 51 hdr->ifi_family = AF_BRIDGE; 52 hdr->__ifi_pad = 0; 53 hdr->ifi_type = dev->type; 54 hdr->ifi_index = dev->ifindex; 55 hdr->ifi_flags = dev_get_flags(dev); 56 hdr->ifi_change = 0; 57 58 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); 59 NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex); 60 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); 61 NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate); 62 63 if (dev->addr_len) 64 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 65 66 if (dev->ifindex != dev->iflink) 67 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); 68 69 if (event == RTM_NEWLINK) 70 NLA_PUT_U8(skb, IFLA_PROTINFO, port->state); 71 72 return nlmsg_end(skb, nlh); 73 74 nla_put_failure: 75 nlmsg_cancel(skb, nlh); 76 return -EMSGSIZE; 77 } 78 79 /* 80 * Notify listeners of a change in port information 81 */ 82 void br_ifinfo_notify(int event, struct net_bridge_port *port) 83 { 84 struct sk_buff *skb; 85 int err = -ENOBUFS; 86 87 pr_debug("bridge notify event=%d\n", event); 88 skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC); 89 if (skb == NULL) 90 goto errout; 91 92 err = br_fill_ifinfo(skb, port, 0, 0, event, 0); 93 if (err < 0) { 94 /* -EMSGSIZE implies BUG in br_nlmsg_size() */ 95 WARN_ON(err == -EMSGSIZE); 96 kfree_skb(skb); 97 goto errout; 98 } 99 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); 100 errout: 101 if (err < 0) 102 rtnl_set_sk_err(RTNLGRP_LINK, err); 103 } 104 105 /* 106 * Dump information about all ports, in response to GETLINK 107 */ 108 static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 109 { 110 struct net_device *dev; 111 int idx; 112 113 idx = 0; 114 for_each_netdev(&init_net, dev) { 115 /* not a bridge port */ 116 if (dev->br_port == NULL || idx < cb->args[0]) 117 goto skip; 118 119 if (br_fill_ifinfo(skb, dev->br_port, NETLINK_CB(cb->skb).pid, 120 cb->nlh->nlmsg_seq, RTM_NEWLINK, 121 NLM_F_MULTI) < 0) 122 break; 123 skip: 124 ++idx; 125 } 126 127 cb->args[0] = idx; 128 129 return skb->len; 130 } 131 132 /* 133 * Change state of port (ie from forwarding to blocking etc) 134 * Used by spanning tree in user space. 135 */ 136 static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 137 { 138 struct ifinfomsg *ifm; 139 struct nlattr *protinfo; 140 struct net_device *dev; 141 struct net_bridge_port *p; 142 u8 new_state; 143 144 if (nlmsg_len(nlh) < sizeof(*ifm)) 145 return -EINVAL; 146 147 ifm = nlmsg_data(nlh); 148 if (ifm->ifi_family != AF_BRIDGE) 149 return -EPFNOSUPPORT; 150 151 protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); 152 if (!protinfo || nla_len(protinfo) < sizeof(u8)) 153 return -EINVAL; 154 155 new_state = nla_get_u8(protinfo); 156 if (new_state > BR_STATE_BLOCKING) 157 return -EINVAL; 158 159 dev = __dev_get_by_index(&init_net, ifm->ifi_index); 160 if (!dev) 161 return -ENODEV; 162 163 p = dev->br_port; 164 if (!p) 165 return -EINVAL; 166 167 /* if kernel STP is running, don't allow changes */ 168 if (p->br->stp_enabled == BR_KERNEL_STP) 169 return -EBUSY; 170 171 if (!netif_running(dev) || 172 (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED)) 173 return -ENETDOWN; 174 175 p->state = new_state; 176 br_log_state(p); 177 return 0; 178 } 179 180 181 int __init br_netlink_init(void) 182 { 183 if (__rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo)) 184 return -ENOBUFS; 185 186 /* Only the first call to __rtnl_register can fail */ 187 __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); 188 189 return 0; 190 } 191 192 void __exit br_netlink_fini(void) 193 { 194 rtnl_unregister_all(PF_BRIDGE); 195 } 196 197