]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/if.h
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / if.h
index caaf9aa1f0a09bf8d91c99ab117a713efd577ebd..166bfa92b52b610e7ae95ca1627018e72204ee11 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -176,20 +176,20 @@ struct if_stats {
 
 /* Link Parameters for Traffic Engineering */
 struct if_link_params {
-       u_int32_t lp_status; /* Status of Link Parameters: */
-       u_int32_t te_metric; /* Traffic Engineering metric */
+       uint32_t lp_status; /* Status of Link Parameters: */
+       uint32_t te_metric; /* Traffic Engineering metric */
        float default_bw;
        float max_bw;                   /* Maximum Bandwidth */
        float max_rsv_bw;               /* Maximum Reservable Bandwidth */
        float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type
                                           (8) */
-       u_int32_t admin_grp;            /* Administrative group */
-       u_int32_t rmt_as;               /* Remote AS number */
+       uint32_t admin_grp;             /* Administrative group */
+       uint32_t rmt_as;                /* Remote AS number */
        struct in_addr rmt_ip;          /* Remote IP address */
-       u_int32_t av_delay;             /* Link Average Delay */
-       u_int32_t min_delay;            /* Link Min Delay */
-       u_int32_t max_delay;            /* Link Max Delay */
-       u_int32_t delay_var;            /* Link Delay Variation */
+       uint32_t av_delay;              /* Link Average Delay */
+       uint32_t min_delay;             /* Link Min Delay */
+       uint32_t max_delay;             /* Link Max Delay */
+       uint32_t delay_var;             /* Link Delay Variation */
        float pkt_loss;                 /* Link Packet Loss */
        float res_bw;                   /* Residual Bandwidth */
        float ava_bw;                   /* Available Bandwidth */
@@ -201,6 +201,8 @@ struct if_link_params {
 
 /* Interface structure */
 struct interface {
+       RB_ENTRY(interface) name_entry, index_entry;
+
        /* Interface name.  This should probably never be changed after the
           interface is created, because the configuration info for this
           interface
@@ -212,13 +214,17 @@ struct interface {
        char name[INTERFACE_NAMSIZ];
 
        /* Interface index (should be IFINDEX_INTERNAL for non-kernel or
-          deleted interfaces). */
+          deleted interfaces).
+          WARNING: the ifindex needs to be changed using the if_set_index()
+          function. Failure to respect this will cause corruption in the data
+          structure used to store the interfaces and if_lookup_by_index() will
+          not work as expected.
+        */
        ifindex_t ifindex;
 #define IFINDEX_INTERNAL       0
-#define IFINDEX_DELETED         INT_MAX
 
        /* Zebra internal interface status */
-       u_char status;
+       uint8_t status;
 #define ZEBRA_INTERFACE_ACTIVE     (1 << 0)
 #define ZEBRA_INTERFACE_SUB        (1 << 1)
 #define ZEBRA_INTERFACE_LINKDETECTION (1 << 2)
@@ -241,7 +247,7 @@ struct interface {
 
        /* Link-layer information and hardware address */
        enum zebra_link_type ll_type;
-       u_char hw_addr[INTERFACE_HWADDR_MAX];
+       uint8_t hw_addr[INTERFACE_HWADDR_MAX];
        int hw_addr_len;
 
        /* interface bandwidth, kbits */
@@ -282,8 +288,48 @@ struct interface {
 
        QOBJ_FIELDS
 };
+
+RB_HEAD(if_name_head, interface);
+RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func);
+RB_HEAD(if_index_head, interface);
+RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_func);
 DECLARE_QOBJ_TYPE(interface)
 
+#define IFNAME_RB_INSERT(vrf, ifp)                                             \
+       if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp)))              \
+               flog_err(EC_LIB_INTERFACE,                                     \
+                        "%s(%s): corruption detected -- interface with this " \
+                        "name exists already in VRF %u!",                     \
+                        __func__, (ifp)->name, (ifp)->vrf_id);
+
+#define IFNAME_RB_REMOVE(vrf, ifp)                                             \
+       if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL)      \
+               flog_err(EC_LIB_INTERFACE,                                     \
+                        "%s(%s): corruption detected -- interface with this " \
+                        "name doesn't exist in VRF %u!",                      \
+                        __func__, (ifp)->name, (ifp)->vrf_id);
+
+#define IFINDEX_RB_INSERT(vrf, ifp)                                            \
+       if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp)))            \
+               flog_err(EC_LIB_INTERFACE,                                     \
+                        "%s(%u): corruption detected -- interface with this " \
+                        "ifindex exists already in VRF %u!",                  \
+                        __func__, (ifp)->ifindex, (ifp)->vrf_id);
+
+#define IFINDEX_RB_REMOVE(vrf, ifp)                                            \
+       if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL)    \
+               flog_err(EC_LIB_INTERFACE,                                     \
+                        "%s(%u): corruption detected -- interface with this " \
+                        "ifindex doesn't exist in VRF %u!",                   \
+                        __func__, (ifp)->ifindex, (ifp)->vrf_id);
+
+#define FOR_ALL_INTERFACES(vrf, ifp)                                           \
+       if (vrf)                                                               \
+               RB_FOREACH (ifp, if_name_head, &vrf->ifaces_by_name)
+
+#define FOR_ALL_INTERFACES_ADDRESSES(ifp, connected, node)                     \
+       for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
+
 /* called from the library code whenever interfaces are created/deleted
  * note: interfaces may not be fully realized at that point; also they
  * may not exist in the system (ifindex = IFINDEX_INTERNAL)
@@ -292,8 +338,8 @@ DECLARE_QOBJ_TYPE(interface)
  * can use 1000+ so they run after the daemon has initialised daemon-specific
  * interface data
  */
-DECLARE_HOOK(if_add, (struct interface *ifp), (ifp))
-DECLARE_KOOH(if_del, (struct interface *ifp), (ifp))
+DECLARE_HOOK(if_add, (struct interface * ifp), (ifp))
+DECLARE_KOOH(if_del, (struct interface * ifp), (ifp))
 
 /* Connected address structure. */
 struct connected {
@@ -301,7 +347,7 @@ struct connected {
        struct interface *ifp;
 
        /* Flags for configuration. */
-       u_char conf;
+       uint8_t conf;
 #define ZEBRA_IFC_REAL         (1 << 0)
 #define ZEBRA_IFC_CONFIGURED   (1 << 1)
 #define ZEBRA_IFC_QUEUED       (1 << 2)
@@ -321,7 +367,7 @@ struct connected {
         */
 
        /* Flags for connected address. */
-       u_char flags;
+       uint8_t flags;
 #define ZEBRA_IFA_SECONDARY    (1 << 0)
 #define ZEBRA_IFA_PEER         (1 << 1)
 #define ZEBRA_IFA_UNNUMBERED   (1 << 2)
@@ -405,10 +451,17 @@ struct nbr_connected {
 #endif /* IFF_VIRTUAL */
 
 /* Prototypes. */
-extern int if_cmp_name_func(char *, char *);
+extern int if_cmp_name_func(const char *p1, const char *p2);
 
+/*
+ * Passing in VRF_UNKNOWN is a valid thing to do, unless we
+ * are creating a new interface.
+ *
+ * This is useful for vrf route-leaking.  So more than anything
+ * else think before you use VRF_UNKNOWN
+ */
 extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
-extern struct interface *if_create(const char *name,  vrf_id_t vrf_id);
+extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
 extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
 extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
                                                 vrf_id_t vrf_id);
@@ -421,8 +474,8 @@ extern struct interface *if_lookup_prefix(struct prefix *prefix,
    by a '\0' character: */
 extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
 extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
-extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id,
-                                       int vty);
+extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id);
+extern void if_set_index(struct interface *ifp, ifindex_t ifindex);
 
 /* Delete the interface, but do not free the structure, and leave it in the
    interface list.  It is often advisable to leave the pseudo interface
@@ -438,12 +491,13 @@ extern int if_is_running(struct interface *);
 extern int if_is_operative(struct interface *);
 extern int if_is_no_ptm_operative(struct interface *);
 extern int if_is_loopback(struct interface *);
+extern int if_is_vrf(struct interface *ifp);
+extern bool if_is_loopback_or_vrf(struct interface *ifp);
 extern int if_is_broadcast(struct interface *);
 extern int if_is_pointopoint(struct interface *);
 extern int if_is_multicast(struct interface *);
-extern void if_init(struct list **);
-extern void if_cmd_init(void);
-extern void if_terminate(struct list **);
+struct vrf;
+extern void if_terminate(struct vrf *vrf);
 extern void if_dump_all(void);
 extern const char *if_flag_dump(unsigned long);
 extern const char *if_link_type_str(enum zebra_link_type);
@@ -478,4 +532,8 @@ struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *);
 struct if_link_params *if_link_params_get(struct interface *);
 void if_link_params_free(struct interface *);
 
+/* Northbound. */
+extern void if_cmd_init(void);
+extern const struct frr_yang_module_info frr_interface_info;
+
 #endif /* _ZEBRA_IF_H */