From: Giuseppe Lettieri Date: Fri, 5 Jul 2013 17:37:07 +0000 (+0200) Subject: Merge commit '4b60911067a82fbdfa87b7c2824412da20287ed8' X-Git-Tag: sliver-openvswitch-1.10.90-3~16 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=c68cc3ef3fa0ee3ade3c86035e5c3d7eb066a605;hp=-c;p=sliver-openvswitch.git Merge commit '4b60911067a82fbdfa87b7c2824412da20287ed8' --- c68cc3ef3fa0ee3ade3c86035e5c3d7eb066a605 diff --combined lib/automake.mk index 8950c054b,f340c6070..9f85de7d2 --- a/lib/automake.mk +++ b/lib/automake.mk @@@ -12,6 -12,8 +12,8 @@@ lib_libopenvswitch_a_SOURCES = lib/aes128.h \ lib/backtrace.c \ lib/backtrace.h \ + lib/bfd.c \ + lib/bfd.h \ lib/bitmap.c \ lib/bitmap.h \ lib/bond.c \ @@@ -88,8 -90,6 +90,8 @@@ lib/multipath.c \ lib/multipath.h \ lib/netdev-dummy.c \ + lib/netdev-tunnel.c \ + lib/netdev-pltap.c \ lib/netdev-provider.h \ lib/netdev-vport.c \ lib/netdev-vport.h \ @@@ -187,8 -187,6 +189,8 @@@ lib/timeval.h \ lib/token-bucket.c \ lib/token-bucket.h \ + lib/tunalloc.c \ + lib/tunalloc.h \ lib/type-props.h \ lib/unaligned.h \ lib/unicode.c \ diff --combined lib/dpif-netdev.c index b945052d5,40f59c379..a37933d5a --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@@ -106,6 -106,7 +106,7 @@@ struct dp_netdev_port int port_no; /* Index into dp_netdev's 'ports'. */ struct list node; /* Element in dp_netdev's 'port_list'. */ struct netdev *netdev; + struct netdev_saved_flags *sf; char *type; /* Port type as requested by user. */ }; @@@ -187,17 -188,10 +188,17 @@@ dpif_netdev_class_is_dummy(const struc return class != &dpif_netdev_class; } +static bool +dpif_netdev_class_is_planetlab(const struct dpif_class *class) +{ + return class == &dpif_planetlab_class; +} + static const char * dpif_netdev_port_open_type(const struct dpif_class *class, const char *type) { return strcmp(type, "internal") ? type + : dpif_netdev_class_is_planetlab(class) ? "pltap" : dpif_netdev_class_is_dummy(class) ? "dummy" : "tap"; } @@@ -223,8 -217,7 +224,8 @@@ choose_port(struct dp_netdev *dp, cons { int port_no; - if (dp->class != &dpif_netdev_class) { + if (dp->class != &dpif_netdev_class && + dp->class != &dpif_planetlab_class) { const char *p; int start_no = 0; @@@ -382,6 -375,7 +383,7 @@@ static in do_add_port(struct dp_netdev *dp, const char *devname, const char *type, uint32_t port_no) { + struct netdev_saved_flags *sf; struct dp_netdev_port *port; struct netdev *netdev; const char *open_type; @@@ -408,7 -402,7 +410,7 @@@ return error; } - error = netdev_turn_flags_on(netdev, NETDEV_PROMISC, false); + error = netdev_turn_flags_on(netdev, NETDEV_PROMISC, &sf); if (error) { netdev_close(netdev); return error; @@@ -417,6 -411,7 +419,7 @@@ port = xmalloc(sizeof *port); port->port_no = port_no; port->netdev = netdev; + port->sf = sf; port->type = xstrdup(type); error = netdev_get_mtu(netdev, &mtu); @@@ -513,6 -508,7 +516,7 @@@ do_del_port(struct dp_netdev *dp, uint3 dp->serial++; netdev_close(port->netdev); + netdev_restore_flags(port->sf); free(port->type); free(port); @@@ -1323,49 -1319,41 +1327,49 @@@ dp_netdev_execute_actions(struct dp_net } } +#define DPIF_NETDEV_CLASS_FUNCTIONS \ + dpif_netdev_enumerate, \ + dpif_netdev_port_open_type, \ + dpif_netdev_open, \ + dpif_netdev_close, \ + dpif_netdev_destroy, \ + dpif_netdev_run, \ + dpif_netdev_wait, \ + dpif_netdev_get_stats, \ + dpif_netdev_port_add, \ + dpif_netdev_port_del, \ + dpif_netdev_port_query_by_number, \ + dpif_netdev_port_query_by_name, \ + dpif_netdev_get_max_ports, \ + NULL, /* port_get_pid */ \ + dpif_netdev_port_dump_start, \ + dpif_netdev_port_dump_next, \ + dpif_netdev_port_dump_done, \ + dpif_netdev_port_poll, \ + dpif_netdev_port_poll_wait, \ + dpif_netdev_flow_get, \ + dpif_netdev_flow_put, \ + dpif_netdev_flow_del, \ + dpif_netdev_flow_flush, \ + dpif_netdev_flow_dump_start, \ + dpif_netdev_flow_dump_next, \ + dpif_netdev_flow_dump_done, \ + dpif_netdev_execute, \ + NULL, /* operate */ \ + dpif_netdev_recv_set, \ + dpif_netdev_queue_to_priority, \ + dpif_netdev_recv, \ + dpif_netdev_recv_wait, \ + dpif_netdev_recv_purge, \ + const struct dpif_class dpif_netdev_class = { "netdev", - dpif_netdev_enumerate, - dpif_netdev_port_open_type, - dpif_netdev_open, - dpif_netdev_close, - dpif_netdev_destroy, - dpif_netdev_run, - dpif_netdev_wait, - dpif_netdev_get_stats, - dpif_netdev_port_add, - dpif_netdev_port_del, - dpif_netdev_port_query_by_number, - dpif_netdev_port_query_by_name, - dpif_netdev_get_max_ports, - NULL, /* port_get_pid */ - dpif_netdev_port_dump_start, - dpif_netdev_port_dump_next, - dpif_netdev_port_dump_done, - dpif_netdev_port_poll, - dpif_netdev_port_poll_wait, - dpif_netdev_flow_get, - dpif_netdev_flow_put, - dpif_netdev_flow_del, - dpif_netdev_flow_flush, - dpif_netdev_flow_dump_start, - dpif_netdev_flow_dump_next, - dpif_netdev_flow_dump_done, - dpif_netdev_execute, - NULL, /* operate */ - dpif_netdev_recv_set, - dpif_netdev_queue_to_priority, - dpif_netdev_recv, - dpif_netdev_recv_wait, - dpif_netdev_recv_purge, + DPIF_NETDEV_CLASS_FUNCTIONS +}; + +const struct dpif_class dpif_planetlab_class = { + "planetlab", + DPIF_NETDEV_CLASS_FUNCTIONS }; static void @@@ -1398,4 -1386,3 +1402,4 @@@ dpif_dummy_register(bool override dpif_dummy_register__("dummy"); } + diff --combined lib/netdev-provider.h index 1442367db,00799b110..c19816ed5 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@@ -38,6 -38,7 +38,7 @@@ struct netdev_dev this device. */ int ref_cnt; /* Times this devices was opened. */ struct shash_node *node; /* Pointer to element in global map. */ + struct list saved_flags_list; /* Contains "struct netdev_saved_flags". */ }; void netdev_dev_init(struct netdev_dev *, const char *name, @@@ -63,9 -64,6 +64,6 @@@ static inline void netdev_dev_assert_cl struct netdev { struct netdev_dev *netdev_dev; /* Parent netdev_dev. */ struct list node; /* Element in global list. */ - - enum netdev_flags save_flags; /* Initial device flags. */ - enum netdev_flags changed_flags; /* Flags that we changed. */ }; void netdev_init(struct netdev *, struct netdev_dev *); @@@ -572,14 -570,14 +570,14 @@@ struct netdev_class int (*arp_lookup)(const struct netdev *netdev, ovs_be32 ip, uint8_t mac[6]); - /* Retrieves the current set of flags on 'netdev' into '*old_flags'. - * Then, turns off the flags that are set to 1 in 'off' and turns on the - * flags that are set to 1 in 'on'. (No bit will be set to 1 in both 'off' - * and 'on'; that is, off & on == 0.) + /* Retrieves the current set of flags on 'dev' into '*old_flags'. Then, + * turns off the flags that are set to 1 in 'off' and turns on the flags + * that are set to 1 in 'on'. (No bit will be set to 1 in both 'off' and + * 'on'; that is, off & on == 0.) * * This function may be invoked from a signal handler. Therefore, it * should not do anything that is not signal-safe (such as logging). */ - int (*update_flags)(struct netdev *netdev, enum netdev_flags off, + int (*update_flags)(struct netdev_dev *dev, enum netdev_flags off, enum netdev_flags on, enum netdev_flags *old_flags); /* Returns a sequence number which indicates changes in one of 'netdev''s @@@ -605,9 -603,6 +603,9 @@@ extern const struct netdev_class netdev extern const struct netdev_class netdev_bsd_class; #endif +extern const struct netdev_class netdev_tunnel_class; +extern const struct netdev_class netdev_pltap_class; + #ifdef __cplusplus } #endif diff --combined lib/netdev.c index 2d6360b58,415cdb4ae..3f8732946 --- a/lib/netdev.c +++ b/lib/netdev.c @@@ -48,6 -48,13 +48,13 @@@ COVERAGE_DEFINE(netdev_sent) COVERAGE_DEFINE(netdev_add_router); COVERAGE_DEFINE(netdev_get_stats); + struct netdev_saved_flags { + struct netdev_dev *dev; + struct list node; /* In struct netdev_dev's saved_flags_list. */ + enum netdev_flags saved_flags; + enum netdev_flags saved_values; + }; + static struct shash netdev_classes = SHASH_INITIALIZER(&netdev_classes); /* All created network devices. */ @@@ -60,8 -67,7 +67,7 @@@ static struct list netdev_list = LIST_I * additional log messages. */ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); - static void close_all_netdevs(void *aux OVS_UNUSED); - static int restore_flags(struct netdev *netdev); + static void restore_all_flags(void *aux OVS_UNUSED); void update_device_args(struct netdev_dev *, const struct shash *args); static void @@@ -72,7 -78,7 +78,7 @@@ netdev_initialize(void if (!inited) { inited = true; - fatal_signal_add_hook(close_all_netdevs, NULL, NULL, true); + fatal_signal_add_hook(restore_all_flags, NULL, NULL, true); netdev_vport_patch_register(); #ifdef LINUX_DATAPATH @@@ -85,8 -91,6 +91,8 @@@ netdev_register_provider(&netdev_tap_class); netdev_register_provider(&netdev_bsd_class); #endif + netdev_register_provider(&netdev_tunnel_class); + netdev_register_provider(&netdev_pltap_class); } } @@@ -304,21 -308,24 +310,24 @@@ netdev_get_tunnel_config(const struct n } } + static void + netdev_dev_unref(struct netdev_dev *dev) + { + ovs_assert(dev->ref_cnt); + if (!--dev->ref_cnt) { + netdev_dev_uninit(dev, true); + } + } + /* Closes and destroys 'netdev'. */ void netdev_close(struct netdev *netdev) { if (netdev) { - struct netdev_dev *netdev_dev = netdev_get_dev(netdev); + struct netdev_dev *dev = netdev_get_dev(netdev); - ovs_assert(netdev_dev->ref_cnt); - netdev_dev->ref_cnt--; netdev_uninit(netdev, true); - - /* If the reference count for the netdev device is zero, destroy it. */ - if (!netdev_dev->ref_cnt) { - netdev_dev_uninit(netdev_dev, true); - } + netdev_dev_unref(dev); } } @@@ -793,37 -800,44 +802,44 @@@ netdev_get_in6(const struct netdev *net } /* On 'netdev', turns off the flags in 'off' and then turns on the flags in - * 'on'. If 'permanent' is true, the changes will persist; otherwise, they - * will be reverted when 'netdev' is closed or the program exits. Returns 0 if - * successful, otherwise a positive errno value. */ + * 'on'. Returns 0 if successful, otherwise a positive errno value. */ static int do_update_flags(struct netdev *netdev, enum netdev_flags off, enum netdev_flags on, enum netdev_flags *old_flagsp, - bool permanent) + struct netdev_saved_flags **sfp) { + struct netdev_dev *dev = netdev_get_dev(netdev); + struct netdev_saved_flags *sf = NULL; enum netdev_flags old_flags; int error; - error = netdev_get_dev(netdev)->netdev_class->update_flags(netdev, - off & ~on, on, &old_flags); + error = dev->netdev_class->update_flags(dev, off & ~on, on, &old_flags); if (error) { VLOG_WARN_RL(&rl, "failed to %s flags for network device %s: %s", off || on ? "set" : "get", netdev_get_name(netdev), strerror(error)); old_flags = 0; - } else if ((off || on) && !permanent) { + } else if ((off || on) && sfp) { enum netdev_flags new_flags = (old_flags & ~off) | on; enum netdev_flags changed_flags = old_flags ^ new_flags; if (changed_flags) { - if (!netdev->changed_flags) { - netdev->save_flags = old_flags; - } - netdev->changed_flags |= changed_flags; + *sfp = sf = xmalloc(sizeof *sf); + sf->dev = dev; + list_push_front(&dev->saved_flags_list, &sf->node); + sf->saved_flags = changed_flags; + sf->saved_values = changed_flags & new_flags; + + dev->ref_cnt++; } } + if (old_flagsp) { *old_flagsp = old_flags; } + if (sfp) { + *sfp = sf; + } + return error; } @@@ -834,40 -848,63 +850,63 @@@ in netdev_get_flags(const struct netdev *netdev_, enum netdev_flags *flagsp) { struct netdev *netdev = CONST_CAST(struct netdev *, netdev_); - return do_update_flags(netdev, 0, 0, flagsp, false); + return do_update_flags(netdev, 0, 0, flagsp, NULL); } /* Sets the flags for 'netdev' to 'flags'. - * If 'permanent' is true, the changes will persist; otherwise, they - * will be reverted when 'netdev' is closed or the program exits. * Returns 0 if successful, otherwise a positive errno value. */ int netdev_set_flags(struct netdev *netdev, enum netdev_flags flags, - bool permanent) + struct netdev_saved_flags **sfp) { - return do_update_flags(netdev, -1, flags, NULL, permanent); + return do_update_flags(netdev, -1, flags, NULL, sfp); } - /* Turns on the specified 'flags' on 'netdev'. - * If 'permanent' is true, the changes will persist; otherwise, they - * will be reverted when 'netdev' is closed or the program exits. - * Returns 0 if successful, otherwise a positive errno value. */ + /* Turns on the specified 'flags' on 'netdev': + * + * - On success, returns 0. If 'sfp' is nonnull, sets '*sfp' to a newly + * allocated 'struct netdev_saved_flags *' that may be passed to + * netdev_restore_flags() to restore the original values of 'flags' on + * 'netdev' (this will happen automatically at program termination if + * netdev_restore_flags() is never called) , or to NULL if no flags were + * actually changed. + * + * - On failure, returns a positive errno value. If 'sfp' is nonnull, sets + * '*sfp' to NULL. */ int netdev_turn_flags_on(struct netdev *netdev, enum netdev_flags flags, - bool permanent) + struct netdev_saved_flags **sfp) { - return do_update_flags(netdev, 0, flags, NULL, permanent); + return do_update_flags(netdev, 0, flags, NULL, sfp); } - /* Turns off the specified 'flags' on 'netdev'. - * If 'permanent' is true, the changes will persist; otherwise, they - * will be reverted when 'netdev' is closed or the program exits. - * Returns 0 if successful, otherwise a positive errno value. */ + /* Turns off the specified 'flags' on 'netdev'. See netdev_turn_flags_on() for + * details of the interface. */ int netdev_turn_flags_off(struct netdev *netdev, enum netdev_flags flags, - bool permanent) + struct netdev_saved_flags **sfp) + { + return do_update_flags(netdev, flags, 0, NULL, sfp); + } + + /* Restores the flags that were saved in 'sf', and destroys 'sf'. + * Does nothing if 'sf' is NULL. */ + void + netdev_restore_flags(struct netdev_saved_flags *sf) { - return do_update_flags(netdev, flags, 0, NULL, permanent); + if (sf) { + struct netdev_dev *dev = sf->dev; + enum netdev_flags old_flags; + + dev->netdev_class->update_flags(dev, + sf->saved_flags & sf->saved_values, + sf->saved_flags & ~sf->saved_values, + &old_flags); + list_remove(&sf->node); + free(sf); + + netdev_dev_unref(dev); + } } /* Looks up the ARP table entry for 'ip' on 'netdev'. If one exists and can be @@@ -1117,7 -1154,7 +1156,7 @@@ netdev_set_qos(struct netdev *netdev if (class->set_qos) { if (!details) { - static struct smap empty = SMAP_INITIALIZER(&empty); + static const struct smap empty = SMAP_INITIALIZER(&empty); details = ∅ } return class->set_qos(netdev, type, details); @@@ -1295,6 -1332,7 +1334,7 @@@ netdev_dev_init(struct netdev_dev *netd netdev_dev->netdev_class = netdev_class; netdev_dev->name = xstrdup(name); netdev_dev->node = shash_add(&netdev_dev_shash, name, netdev_dev); + list_init(&netdev_dev->saved_flags_list); } /* Undoes the results of initialization. @@@ -1310,6 -1348,7 +1350,7 @@@ netdev_dev_uninit(struct netdev_dev *ne char *name = netdev_dev->name; ovs_assert(!netdev_dev->ref_cnt); + ovs_assert(list_is_empty(&netdev_dev->saved_flags_list)); shash_delete(&netdev_dev_shash, netdev_dev->node); @@@ -1392,20 -1431,12 +1433,12 @@@ netdev_init(struct netdev *netdev, stru void netdev_uninit(struct netdev *netdev, bool close) { - /* Restore flags that we changed, if any. */ - int error = restore_flags(netdev); list_remove(&netdev->node); - if (error) { - VLOG_WARN("failed to restore network device flags on %s: %s", - netdev_get_name(netdev), strerror(error)); - } - if (close) { netdev_get_dev(netdev)->netdev_class->close(netdev); } } - /* Returns the class type of 'netdev'. * * The caller must not free the returned value. */ @@@ -1415,7 -1446,6 +1448,6 @@@ netdev_get_type(const struct netdev *ne return netdev_get_dev(netdev)->netdev_class->type; } - const char * netdev_get_type_from_name(const char *name) { @@@ -1429,31 -1459,32 +1461,32 @@@ netdev_get_dev(const struct netdev *net return netdev->netdev_dev; } - /* Restore the network device flags on 'netdev' to those that were active - * before we changed them. Returns 0 if successful, otherwise a positive - * errno value. - * - * To avoid reentry, the caller must ensure that fatal signals are blocked. */ - static int - restore_flags(struct netdev *netdev) - { - if (netdev->changed_flags) { - enum netdev_flags restore = netdev->save_flags & netdev->changed_flags; - enum netdev_flags old_flags; - return netdev_get_dev(netdev)->netdev_class->update_flags(netdev, - netdev->changed_flags & ~restore, - restore, &old_flags); - } - return 0; - } - - /* Close all netdevs on shutdown so they can do any needed cleanup such as - * destroying devices, restoring flags, etc. */ + /* Restores all flags that have been saved with netdev_save_flags() and not yet + * restored with netdev_restore_flags(). */ static void - close_all_netdevs(void *aux OVS_UNUSED) + restore_all_flags(void *aux OVS_UNUSED) { - struct netdev *netdev, *next; - LIST_FOR_EACH_SAFE(netdev, next, node, &netdev_list) { - netdev_close(netdev); + struct shash_node *node; + + SHASH_FOR_EACH (node, &netdev_dev_shash) { + struct netdev_dev *dev = node->data; + const struct netdev_saved_flags *sf; + enum netdev_flags saved_values; + enum netdev_flags saved_flags; + + saved_values = saved_flags = 0; + LIST_FOR_EACH (sf, node, &dev->saved_flags_list) { + saved_flags |= sf->saved_flags; + saved_values &= ~sf->saved_flags; + saved_values |= sf->saved_flags & sf->saved_values; + } + if (saved_flags) { + enum netdev_flags old_flags; + + dev->netdev_class->update_flags(dev, + saved_flags & saved_values, + saved_flags & ~saved_values, + &old_flags); + } } }