X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=30cd0f6390695d9a98e9a05fed3f05ef83754827;hb=a39c3ff9f586d3416976d3c3bd095fa81d73efa0;hp=c0e0c40c5d2df63ef950da1b27192c150c9d43fc;hpb=7fa0f73fb284b4406bcd085ee62552891b3fa6cd;p=sliver-openvswitch.git diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index c0e0c40c5..30cd0f639 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -139,6 +139,8 @@ struct tc { * Written only by TC implementation. */ }; +#define TC_INITIALIZER(TC, OPS) { OPS, HMAP_INITIALIZER(&(TC)->queues) } + /* One traffic control queue. * * Each TC implementation subclasses this with whatever additional data it @@ -311,7 +313,7 @@ static const struct tc_ops tc_ops_hfsc; static const struct tc_ops tc_ops_default; static const struct tc_ops tc_ops_other; -static const struct tc_ops *tcs[] = { +static const struct tc_ops *const tcs[] = { &tc_ops_htb, /* Hierarchy token bucket (see tc-htb(8)). */ &tc_ops_hfsc, /* Hierarchical fair service curve. */ &tc_ops_default, /* Default qdisc (see tc-pfifo_fast(8)). */ @@ -420,7 +422,7 @@ static int netdev_linux_do_ioctl(const char *name, struct ifreq *, int cmd, static int netdev_linux_get_ipv4(const struct netdev *, struct in_addr *, int cmd, const char *cmd_name); static int get_flags(const struct netdev_dev *, unsigned int *flags); -static int set_flags(struct netdev *, unsigned int flags); +static int set_flags(const char *, unsigned int flags); static int do_get_ifindex(const char *netdev_name); static int get_ifindex(const struct netdev *, int *ifindexp); static int do_set_addr(struct netdev *netdev, @@ -1002,8 +1004,8 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev_)); + struct netdev_saved_flags *sf = NULL; int error; - bool up_again = false; if (netdev_dev->cache_valid & VALID_ETHERADDR) { if (netdev_dev->ether_addr_error) { @@ -1020,8 +1022,7 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, enum netdev_flags flags; if (!netdev_get_flags(netdev_, &flags) && (flags & NETDEV_UP)) { - netdev_turn_flags_off(netdev_, NETDEV_UP, false); - up_again = true; + netdev_turn_flags_off(netdev_, NETDEV_UP, &sf); } } error = set_etheraddr(netdev_get_name(netdev_), mac); @@ -1033,9 +1034,7 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, } } - if (up_again) { - netdev_turn_flags_on(netdev_, NETDEV_UP, false); - } + netdev_restore_flags(sf); return error; } @@ -1851,7 +1850,7 @@ static int netdev_linux_get_qos_types(const struct netdev *netdev OVS_UNUSED, struct sset *types) { - const struct tc_ops **opsp; + const struct tc_ops *const *opsp; for (opsp = tcs; *opsp != NULL; opsp++) { const struct tc_ops *ops = *opsp; @@ -1865,7 +1864,7 @@ netdev_linux_get_qos_types(const struct netdev *netdev OVS_UNUSED, static const struct tc_ops * tc_lookup_ovs_name(const char *name) { - const struct tc_ops **opsp; + const struct tc_ops *const *opsp; for (opsp = tcs; *opsp != NULL; opsp++) { const struct tc_ops *ops = *opsp; @@ -1879,7 +1878,7 @@ tc_lookup_ovs_name(const char *name) static const struct tc_ops * tc_lookup_linux_name(const char *name) { - const struct tc_ops **opsp; + const struct tc_ops *const *opsp; for (opsp = tcs; *opsp != NULL; opsp++) { const struct tc_ops *ops = *opsp; @@ -2448,19 +2447,19 @@ iff_to_nd_flags(int iff) } static int -netdev_linux_update_flags(struct netdev *netdev, enum netdev_flags off, +netdev_linux_update_flags(struct netdev_dev *dev_, enum netdev_flags off, enum netdev_flags on, enum netdev_flags *old_flagsp) { struct netdev_dev_linux *netdev_dev; int old_flags, new_flags; int error = 0; - netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); + netdev_dev = netdev_dev_linux_cast(dev_); old_flags = netdev_dev->ifi_flags; *old_flagsp = iff_to_nd_flags(old_flags); new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on); if (new_flags != old_flags) { - error = set_flags(netdev, new_flags); + error = set_flags(netdev_dev_get_name(dev_), new_flags); get_flags(&netdev_dev->netdev_dev, &netdev_dev->ifi_flags); } return error; @@ -3559,13 +3558,11 @@ default_install__(struct netdev *netdev) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); - static struct tc *tc; + static const struct tc tc = TC_INITIALIZER(&tc, &tc_ops_default); - if (!tc) { - tc = xmalloc(sizeof *tc); - tc_init(tc, &tc_ops_default); - } - netdev_dev->tc = tc; + /* Nothing but a tc class implementation is allowed to write to a tc. This + * class never does that, so we can legitimately use a const tc object. */ + netdev_dev->tc = CONST_CAST(struct tc *, &tc); } static int @@ -3608,13 +3605,11 @@ other_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); - static struct tc *tc; + static const struct tc tc = TC_INITIALIZER(&tc, &tc_ops_other); - if (!tc) { - tc = xmalloc(sizeof *tc); - tc_init(tc, &tc_ops_other); - } - netdev_dev->tc = tc; + /* Nothing but a tc class implementation is allowed to write to a tc. This + * class never does that, so we can legitimately use a const tc object. */ + netdev_dev->tc = CONST_CAST(struct tc *, &tc); return 0; } @@ -4483,13 +4478,12 @@ get_flags(const struct netdev_dev *dev, unsigned int *flags) } static int -set_flags(struct netdev *netdev, unsigned int flags) +set_flags(const char *name, unsigned int flags) { struct ifreq ifr; ifr.ifr_flags = flags; - return netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, SIOCSIFFLAGS, - "SIOCSIFFLAGS"); + return netdev_linux_do_ioctl(name, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS"); } static int