Before, it was possible for records in the configuration database to
disappear, so all of the ovsrec pointers inside bridge structures had
comments cautioning against their use except during reconfiguration. But
now that the bridge has direct control over when ovsdb_idl_run() is called,
it can ensure that bridge_reconfigure() is always called immediately
whenever the IDL data structures change. That means that we can use the
ovsrec configuration at any time after the reconfiguration process
initializes them, not just during reconfiguration.
long long delay_expires; /* Time after which 'enabled' may change. */
/* These members are valid only after bridge_reconfigure() causes them to
long long delay_expires; /* Time after which 'enabled' may change. */
/* These members are valid only after bridge_reconfigure() causes them to
int dp_ifidx; /* Index within kernel datapath. */
struct netdev *netdev; /* Network device. */
bool enabled; /* May be chosen for flows? */
int dp_ifidx; /* Index within kernel datapath. */
struct netdev *netdev; /* Network device. */
bool enabled; /* May be chosen for flows? */
-
- /* This member is only valid *during* bridge_reconfigure(). */
const struct ovsrec_interface *cfg;
};
const struct ovsrec_interface *cfg;
};
int vlan; /* -1=trunk port, else a 12-bit VLAN ID. */
unsigned long *trunks; /* Bitmap of trunked VLANs, if 'vlan' == -1.
* NULL if all VLANs are trunked. */
int vlan; /* -1=trunk port, else a 12-bit VLAN ID. */
unsigned long *trunks; /* Bitmap of trunked VLANs, if 'vlan' == -1.
* NULL if all VLANs are trunked. */
+ const struct ovsrec_port *cfg;
char *name;
/* An ordinary bridge port has 1 interface.
char *name;
/* An ordinary bridge port has 1 interface.
mirror_mask_t src_mirrors; /* Mirrors triggered when packet received. */
mirror_mask_t dst_mirrors; /* Mirrors triggered when packet sent. */
bool is_mirror_output_port; /* Does port mirroring send frames here? */
mirror_mask_t src_mirrors; /* Mirrors triggered when packet received. */
mirror_mask_t dst_mirrors; /* Mirrors triggered when packet sent. */
bool is_mirror_output_port; /* Does port mirroring send frames here? */
-
- /* This member is only valid *during* bridge_reconfigure(). */
- const struct ovsrec_port *cfg;
};
#define DP_MAX_PORTS 255
};
#define DP_MAX_PORTS 255
char *name; /* User-specified arbitrary name. */
struct mac_learning *ml; /* MAC learning table. */
uint8_t default_ea[ETH_ADDR_LEN]; /* Default MAC. */
char *name; /* User-specified arbitrary name. */
struct mac_learning *ml; /* MAC learning table. */
uint8_t default_ea[ETH_ADDR_LEN]; /* Default MAC. */
+ const struct ovsrec_bridge *cfg;
/* OpenFlow switch processing. */
struct ofproto *ofproto; /* OpenFlow switch. */
/* OpenFlow switch processing. */
struct ofproto *ofproto; /* OpenFlow switch. */
/* Port mirroring. */
struct mirror *mirrors[MAX_MIRRORS];
/* Port mirroring. */
struct mirror *mirrors[MAX_MIRRORS];
-
- /* This member is only valid *during* bridge_reconfigure(). */
- const struct ovsrec_bridge *cfg;
};
/* List of all bridges. */
};
/* List of all bridges. */
ovsrec_open_vswitch_set_cur_cfg(cfg, cfg->next_cfg);
ovsdb_idl_txn_commit(txn);
ovsdb_idl_txn_destroy(txn); /* XXX */
ovsrec_open_vswitch_set_cur_cfg(cfg, cfg->next_cfg);
ovsdb_idl_txn_commit(txn);
ovsdb_idl_txn_destroy(txn); /* XXX */
+ } else {
+ /* We still need to reconfigure to avoid dangling pointers to
+ * now-destroyed ovsrec structures inside bridge data. */
+ static const struct ovsrec_open_vswitch null_cfg;
+
+ bridge_reconfigure(&null_cfg);