diff options
| -rw-r--r-- | include/linux/if.h | 26 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 35 | ||||
| -rw-r--r-- | include/linux/rtnetlink.h | 2 | ||||
| -rw-r--r-- | net/core/dev.c | 14 | ||||
| -rw-r--r-- | net/core/link_watch.c | 40 | ||||
| -rw-r--r-- | net/core/net-sysfs.c | 41 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 50 |
7 files changed, 200 insertions, 8 deletions
diff --git a/include/linux/if.h b/include/linux/if.h index 12c6f6d157c3..374e20ad8b0d 100644 --- a/include/linux/if.h +++ b/include/linux/if.h | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | #define IFF_LOOPBACK 0x8 /* is a loopback net */ | 33 | #define IFF_LOOPBACK 0x8 /* is a loopback net */ |
| 34 | #define IFF_POINTOPOINT 0x10 /* interface is has p-p link */ | 34 | #define IFF_POINTOPOINT 0x10 /* interface is has p-p link */ |
| 35 | #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ | 35 | #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ |
| 36 | #define IFF_RUNNING 0x40 /* interface running and carrier ok */ | 36 | #define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */ |
| 37 | #define IFF_NOARP 0x80 /* no ARP protocol */ | 37 | #define IFF_NOARP 0x80 /* no ARP protocol */ |
| 38 | #define IFF_PROMISC 0x100 /* receive all packets */ | 38 | #define IFF_PROMISC 0x100 /* receive all packets */ |
| 39 | #define IFF_ALLMULTI 0x200 /* receive all multicast packets*/ | 39 | #define IFF_ALLMULTI 0x200 /* receive all multicast packets*/ |
| @@ -43,12 +43,16 @@ | |||
| 43 | 43 | ||
| 44 | #define IFF_MULTICAST 0x1000 /* Supports multicast */ | 44 | #define IFF_MULTICAST 0x1000 /* Supports multicast */ |
| 45 | 45 | ||
| 46 | #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING) | ||
| 47 | |||
| 48 | #define IFF_PORTSEL 0x2000 /* can set media type */ | 46 | #define IFF_PORTSEL 0x2000 /* can set media type */ |
| 49 | #define IFF_AUTOMEDIA 0x4000 /* auto media select active */ | 47 | #define IFF_AUTOMEDIA 0x4000 /* auto media select active */ |
| 50 | #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ | 48 | #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ |
| 51 | 49 | ||
| 50 | #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ | ||
| 51 | #define IFF_DORMANT 0x20000 /* driver signals dormant */ | ||
| 52 | |||
| 53 | #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|\ | ||
| 54 | IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) | ||
| 55 | |||
| 52 | /* Private (from user) interface flags (netdevice->priv_flags). */ | 56 | /* Private (from user) interface flags (netdevice->priv_flags). */ |
| 53 | #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ | 57 | #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ |
| 54 | #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ | 58 | #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ |
| @@ -83,6 +87,22 @@ | |||
| 83 | #define IF_PROTO_FR_ETH_PVC 0x200B | 87 | #define IF_PROTO_FR_ETH_PVC 0x200B |
| 84 | #define IF_PROTO_RAW 0x200C /* RAW Socket */ | 88 | #define IF_PROTO_RAW 0x200C /* RAW Socket */ |
| 85 | 89 | ||
| 90 | /* RFC 2863 operational status */ | ||
| 91 | enum { | ||
| 92 | IF_OPER_UNKNOWN, | ||
| 93 | IF_OPER_NOTPRESENT, | ||
| 94 | IF_OPER_DOWN, | ||
| 95 | IF_OPER_LOWERLAYERDOWN, | ||
| 96 | IF_OPER_TESTING, | ||
| 97 | IF_OPER_DORMANT, | ||
| 98 | IF_OPER_UP, | ||
| 99 | }; | ||
| 100 | |||
| 101 | /* link modes */ | ||
| 102 | enum { | ||
| 103 | IF_LINK_MODE_DEFAULT, | ||
| 104 | IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */ | ||
| 105 | }; | ||
| 86 | 106 | ||
| 87 | /* | 107 | /* |
| 88 | * Device mapping structure. I'd just gone off and designed a | 108 | * Device mapping structure. I'd just gone off and designed a |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7fda03d338d1..b825be201bce 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -230,7 +230,8 @@ enum netdev_state_t | |||
| 230 | __LINK_STATE_SCHED, | 230 | __LINK_STATE_SCHED, |
| 231 | __LINK_STATE_NOCARRIER, | 231 | __LINK_STATE_NOCARRIER, |
| 232 | __LINK_STATE_RX_SCHED, | 232 | __LINK_STATE_RX_SCHED, |
| 233 | __LINK_STATE_LINKWATCH_PENDING | 233 | __LINK_STATE_LINKWATCH_PENDING, |
| 234 | __LINK_STATE_DORMANT, | ||
| 234 | }; | 235 | }; |
| 235 | 236 | ||
| 236 | 237 | ||
| @@ -335,11 +336,14 @@ struct net_device | |||
| 335 | */ | 336 | */ |
| 336 | 337 | ||
| 337 | 338 | ||
| 338 | unsigned short flags; /* interface flags (a la BSD) */ | 339 | unsigned int flags; /* interface flags (a la BSD) */ |
| 339 | unsigned short gflags; | 340 | unsigned short gflags; |
| 340 | unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */ | 341 | unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */ |
| 341 | unsigned short padded; /* How much padding added by alloc_netdev() */ | 342 | unsigned short padded; /* How much padding added by alloc_netdev() */ |
| 342 | 343 | ||
| 344 | unsigned char operstate; /* RFC2863 operstate */ | ||
| 345 | unsigned char link_mode; /* mapping policy to operstate */ | ||
| 346 | |||
| 343 | unsigned mtu; /* interface MTU value */ | 347 | unsigned mtu; /* interface MTU value */ |
| 344 | unsigned short type; /* interface hardware type */ | 348 | unsigned short type; /* interface hardware type */ |
| 345 | unsigned short hard_header_len; /* hardware hdr length */ | 349 | unsigned short hard_header_len; /* hardware hdr length */ |
| @@ -714,6 +718,10 @@ static inline void dev_put(struct net_device *dev) | |||
| 714 | /* Carrier loss detection, dial on demand. The functions netif_carrier_on | 718 | /* Carrier loss detection, dial on demand. The functions netif_carrier_on |
| 715 | * and _off may be called from IRQ context, but it is caller | 719 | * and _off may be called from IRQ context, but it is caller |
| 716 | * who is responsible for serialization of these calls. | 720 | * who is responsible for serialization of these calls. |
| 721 | * | ||
| 722 | * The name carrier is inappropriate, these functions should really be | ||
| 723 | * called netif_lowerlayer_*() because they represent the state of any | ||
| 724 | * kind of lower layer not just hardware media. | ||
| 717 | */ | 725 | */ |
| 718 | 726 | ||
| 719 | extern void linkwatch_fire_event(struct net_device *dev); | 727 | extern void linkwatch_fire_event(struct net_device *dev); |
| @@ -729,6 +737,29 @@ extern void netif_carrier_on(struct net_device *dev); | |||
| 729 | 737 | ||
| 730 | extern void netif_carrier_off(struct net_device *dev); | 738 | extern void netif_carrier_off(struct net_device *dev); |
| 731 | 739 | ||
| 740 | static inline void netif_dormant_on(struct net_device *dev) | ||
| 741 | { | ||
| 742 | if (!test_and_set_bit(__LINK_STATE_DORMANT, &dev->state)) | ||
| 743 | linkwatch_fire_event(dev); | ||
| 744 | } | ||
| 745 | |||
| 746 | static inline void netif_dormant_off(struct net_device *dev) | ||
| 747 | { | ||
| 748 | if (test_and_clear_bit(__LINK_STATE_DORMANT, &dev->state)) | ||
| 749 | linkwatch_fire_event(dev); | ||
| 750 | } | ||
| 751 | |||
| 752 | static inline int netif_dormant(const struct net_device *dev) | ||
| 753 | { | ||
| 754 | return test_bit(__LINK_STATE_DORMANT, &dev->state); | ||
| 755 | } | ||
| 756 | |||
| 757 | |||
| 758 | static inline int netif_oper_up(const struct net_device *dev) { | ||
| 759 | return (dev->operstate == IF_OPER_UP || | ||
| 760 | dev->operstate == IF_OPER_UNKNOWN /* backward compat */); | ||
| 761 | } | ||
| 762 | |||
| 732 | /* Hot-plugging. */ | 763 | /* Hot-plugging. */ |
| 733 | static inline int netif_device_present(struct net_device *dev) | 764 | static inline int netif_device_present(struct net_device *dev) |
| 734 | { | 765 | { |
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d50482ba27fe..edccefb45188 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
| @@ -733,6 +733,8 @@ enum | |||
| 733 | #define IFLA_MAP IFLA_MAP | 733 | #define IFLA_MAP IFLA_MAP |
| 734 | IFLA_WEIGHT, | 734 | IFLA_WEIGHT, |
| 735 | #define IFLA_WEIGHT IFLA_WEIGHT | 735 | #define IFLA_WEIGHT IFLA_WEIGHT |
| 736 | IFLA_OPERSTATE, | ||
| 737 | IFLA_LINKMODE, | ||
| 736 | __IFLA_MAX | 738 | __IFLA_MAX |
| 737 | }; | 739 | }; |
| 738 | 740 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index ef56c035d44e..8763c99fcb84 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2174,12 +2174,20 @@ unsigned dev_get_flags(const struct net_device *dev) | |||
| 2174 | 2174 | ||
| 2175 | flags = (dev->flags & ~(IFF_PROMISC | | 2175 | flags = (dev->flags & ~(IFF_PROMISC | |
| 2176 | IFF_ALLMULTI | | 2176 | IFF_ALLMULTI | |
| 2177 | IFF_RUNNING)) | | 2177 | IFF_RUNNING | |
| 2178 | IFF_LOWER_UP | | ||
| 2179 | IFF_DORMANT)) | | ||
| 2178 | (dev->gflags & (IFF_PROMISC | | 2180 | (dev->gflags & (IFF_PROMISC | |
| 2179 | IFF_ALLMULTI)); | 2181 | IFF_ALLMULTI)); |
| 2180 | 2182 | ||
| 2181 | if (netif_running(dev) && netif_carrier_ok(dev)) | 2183 | if (netif_running(dev)) { |
| 2182 | flags |= IFF_RUNNING; | 2184 | if (netif_oper_up(dev)) |
| 2185 | flags |= IFF_RUNNING; | ||
| 2186 | if (netif_carrier_ok(dev)) | ||
| 2187 | flags |= IFF_LOWER_UP; | ||
| 2188 | if (netif_dormant(dev)) | ||
| 2189 | flags |= IFF_DORMANT; | ||
| 2190 | } | ||
| 2183 | 2191 | ||
| 2184 | return flags; | 2192 | return flags; |
| 2185 | } | 2193 | } |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index d43d1201275c..e82a451d330b 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
| @@ -49,6 +49,45 @@ struct lw_event { | |||
| 49 | /* Avoid kmalloc() for most systems */ | 49 | /* Avoid kmalloc() for most systems */ |
| 50 | static struct lw_event singleevent; | 50 | static struct lw_event singleevent; |
| 51 | 51 | ||
| 52 | static unsigned char default_operstate(const struct net_device *dev) | ||
| 53 | { | ||
| 54 | if (!netif_carrier_ok(dev)) | ||
| 55 | return (dev->ifindex != dev->iflink ? | ||
| 56 | IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN); | ||
| 57 | |||
| 58 | if (netif_dormant(dev)) | ||
| 59 | return IF_OPER_DORMANT; | ||
| 60 | |||
| 61 | return IF_OPER_UP; | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | static void rfc2863_policy(struct net_device *dev) | ||
| 66 | { | ||
| 67 | unsigned char operstate = default_operstate(dev); | ||
| 68 | |||
| 69 | if (operstate == dev->operstate) | ||
| 70 | return; | ||
| 71 | |||
| 72 | write_lock_bh(&dev_base_lock); | ||
| 73 | |||
| 74 | switch(dev->link_mode) { | ||
| 75 | case IF_LINK_MODE_DORMANT: | ||
| 76 | if (operstate == IF_OPER_UP) | ||
| 77 | operstate = IF_OPER_DORMANT; | ||
| 78 | break; | ||
| 79 | |||
| 80 | case IF_LINK_MODE_DEFAULT: | ||
| 81 | default: | ||
| 82 | break; | ||
| 83 | }; | ||
| 84 | |||
| 85 | dev->operstate = operstate; | ||
| 86 | |||
| 87 | write_unlock_bh(&dev_base_lock); | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 52 | /* Must be called with the rtnl semaphore held */ | 91 | /* Must be called with the rtnl semaphore held */ |
| 53 | void linkwatch_run_queue(void) | 92 | void linkwatch_run_queue(void) |
| 54 | { | 93 | { |
| @@ -74,6 +113,7 @@ void linkwatch_run_queue(void) | |||
| 74 | */ | 113 | */ |
| 75 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); | 114 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); |
| 76 | 115 | ||
| 116 | rfc2863_policy(dev); | ||
| 77 | if (dev->flags & IFF_UP) { | 117 | if (dev->flags & IFF_UP) { |
| 78 | if (netif_carrier_ok(dev)) { | 118 | if (netif_carrier_ok(dev)) { |
| 79 | WARN_ON(dev->qdisc_sleeping == &noop_qdisc); | 119 | WARN_ON(dev->qdisc_sleeping == &noop_qdisc); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index e8b2acbc8ea2..21b68464cabb 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -91,6 +91,7 @@ NETDEVICE_SHOW(iflink, fmt_dec); | |||
| 91 | NETDEVICE_SHOW(ifindex, fmt_dec); | 91 | NETDEVICE_SHOW(ifindex, fmt_dec); |
| 92 | NETDEVICE_SHOW(features, fmt_long_hex); | 92 | NETDEVICE_SHOW(features, fmt_long_hex); |
| 93 | NETDEVICE_SHOW(type, fmt_dec); | 93 | NETDEVICE_SHOW(type, fmt_dec); |
| 94 | NETDEVICE_SHOW(link_mode, fmt_dec); | ||
| 94 | 95 | ||
| 95 | /* use same locking rules as GIFHWADDR ioctl's */ | 96 | /* use same locking rules as GIFHWADDR ioctl's */ |
| 96 | static ssize_t format_addr(char *buf, const unsigned char *addr, int len) | 97 | static ssize_t format_addr(char *buf, const unsigned char *addr, int len) |
| @@ -133,6 +134,43 @@ static ssize_t show_carrier(struct class_device *dev, char *buf) | |||
| 133 | return -EINVAL; | 134 | return -EINVAL; |
| 134 | } | 135 | } |
| 135 | 136 | ||
| 137 | static ssize_t show_dormant(struct class_device *dev, char *buf) | ||
| 138 | { | ||
| 139 | struct net_device *netdev = to_net_dev(dev); | ||
| 140 | |||
| 141 | if (netif_running(netdev)) | ||
| 142 | return sprintf(buf, fmt_dec, !!netif_dormant(netdev)); | ||
| 143 | |||
| 144 | return -EINVAL; | ||
| 145 | } | ||
| 146 | |||
| 147 | static const char *operstates[] = { | ||
| 148 | "unknown", | ||
| 149 | "notpresent", /* currently unused */ | ||
| 150 | "down", | ||
| 151 | "lowerlayerdown", | ||
| 152 | "testing", /* currently unused */ | ||
| 153 | "dormant", | ||
| 154 | "up" | ||
| 155 | }; | ||
| 156 | |||
| 157 | static ssize_t show_operstate(struct class_device *dev, char *buf) | ||
| 158 | { | ||
| 159 | const struct net_device *netdev = to_net_dev(dev); | ||
| 160 | unsigned char operstate; | ||
| 161 | |||
| 162 | read_lock(&dev_base_lock); | ||
| 163 | operstate = netdev->operstate; | ||
| 164 | if (!netif_running(netdev)) | ||
| 165 | operstate = IF_OPER_DOWN; | ||
| 166 | read_unlock(&dev_base_lock); | ||
| 167 | |||
| 168 | if (operstate >= sizeof(operstates)) | ||
| 169 | return -EINVAL; /* should not happen */ | ||
| 170 | |||
| 171 | return sprintf(buf, "%s\n", operstates[operstate]); | ||
| 172 | } | ||
| 173 | |||
| 136 | /* read-write attributes */ | 174 | /* read-write attributes */ |
| 137 | NETDEVICE_SHOW(mtu, fmt_dec); | 175 | NETDEVICE_SHOW(mtu, fmt_dec); |
| 138 | 176 | ||
| @@ -190,9 +228,12 @@ static struct class_device_attribute net_class_attributes[] = { | |||
| 190 | __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), | 228 | __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), |
| 191 | __ATTR(features, S_IRUGO, show_features, NULL), | 229 | __ATTR(features, S_IRUGO, show_features, NULL), |
| 192 | __ATTR(type, S_IRUGO, show_type, NULL), | 230 | __ATTR(type, S_IRUGO, show_type, NULL), |
| 231 | __ATTR(link_mode, S_IRUGO, show_link_mode, NULL), | ||
| 193 | __ATTR(address, S_IRUGO, show_address, NULL), | 232 | __ATTR(address, S_IRUGO, show_address, NULL), |
| 194 | __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), | 233 | __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), |
| 195 | __ATTR(carrier, S_IRUGO, show_carrier, NULL), | 234 | __ATTR(carrier, S_IRUGO, show_carrier, NULL), |
| 235 | __ATTR(dormant, S_IRUGO, show_dormant, NULL), | ||
| 236 | __ATTR(operstate, S_IRUGO, show_operstate, NULL), | ||
| 196 | __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), | 237 | __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), |
| 197 | __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), | 238 | __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), |
| 198 | __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, | 239 | __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index eca2976abb25..1c15a907066f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -179,6 +179,33 @@ rtattr_failure: | |||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | 181 | ||
| 182 | static void set_operstate(struct net_device *dev, unsigned char transition) | ||
| 183 | { | ||
| 184 | unsigned char operstate = dev->operstate; | ||
| 185 | |||
| 186 | switch(transition) { | ||
| 187 | case IF_OPER_UP: | ||
| 188 | if ((operstate == IF_OPER_DORMANT || | ||
| 189 | operstate == IF_OPER_UNKNOWN) && | ||
| 190 | !netif_dormant(dev)) | ||
| 191 | operstate = IF_OPER_UP; | ||
| 192 | break; | ||
| 193 | |||
| 194 | case IF_OPER_DORMANT: | ||
| 195 | if (operstate == IF_OPER_UP || | ||
| 196 | operstate == IF_OPER_UNKNOWN) | ||
| 197 | operstate = IF_OPER_DORMANT; | ||
| 198 | break; | ||
| 199 | }; | ||
| 200 | |||
| 201 | if (dev->operstate != operstate) { | ||
| 202 | write_lock_bh(&dev_base_lock); | ||
| 203 | dev->operstate = operstate; | ||
| 204 | write_unlock_bh(&dev_base_lock); | ||
| 205 | netdev_state_change(dev); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 182 | static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 209 | static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
| 183 | int type, u32 pid, u32 seq, u32 change, | 210 | int type, u32 pid, u32 seq, u32 change, |
| 184 | unsigned int flags) | 211 | unsigned int flags) |
| @@ -209,6 +236,13 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 209 | } | 236 | } |
| 210 | 237 | ||
| 211 | if (1) { | 238 | if (1) { |
| 239 | u8 operstate = netif_running(dev)?dev->operstate:IF_OPER_DOWN; | ||
| 240 | u8 link_mode = dev->link_mode; | ||
| 241 | RTA_PUT(skb, IFLA_OPERSTATE, sizeof(operstate), &operstate); | ||
| 242 | RTA_PUT(skb, IFLA_LINKMODE, sizeof(link_mode), &link_mode); | ||
| 243 | } | ||
| 244 | |||
| 245 | if (1) { | ||
| 212 | struct rtnl_link_ifmap map = { | 246 | struct rtnl_link_ifmap map = { |
| 213 | .mem_start = dev->mem_start, | 247 | .mem_start = dev->mem_start, |
| 214 | .mem_end = dev->mem_end, | 248 | .mem_end = dev->mem_end, |
| @@ -399,6 +433,22 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 399 | dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); | 433 | dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); |
| 400 | } | 434 | } |
| 401 | 435 | ||
| 436 | if (ida[IFLA_OPERSTATE - 1]) { | ||
| 437 | if (ida[IFLA_OPERSTATE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) | ||
| 438 | goto out; | ||
| 439 | |||
| 440 | set_operstate(dev, *((u8 *) RTA_DATA(ida[IFLA_OPERSTATE - 1]))); | ||
| 441 | } | ||
| 442 | |||
| 443 | if (ida[IFLA_LINKMODE - 1]) { | ||
| 444 | if (ida[IFLA_LINKMODE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) | ||
| 445 | goto out; | ||
| 446 | |||
| 447 | write_lock_bh(&dev_base_lock); | ||
| 448 | dev->link_mode = *((u8 *) RTA_DATA(ida[IFLA_LINKMODE - 1])); | ||
| 449 | write_unlock_bh(&dev_base_lock); | ||
| 450 | } | ||
| 451 | |||
| 402 | if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { | 452 | if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { |
| 403 | char ifname[IFNAMSIZ]; | 453 | char ifname[IFNAMSIZ]; |
| 404 | 454 | ||
