diff --git a/src/confd/src/cni.c b/src/confd/src/cni.c index eaee5a40..701b1a4c 100644 --- a/src/confd/src/cni.c +++ b/src/confd/src/cni.c @@ -6,6 +6,7 @@ #include "core.h" #include "cni.h" +#include "ietf-interfaces.h" #define CNI_NAME "/etc/cni/net.d/%s.conflist" @@ -86,13 +87,13 @@ FILE *cni_popen(const char *fmt, const char *ifname) return popenf("re", "nsenter -t %d -n %s", pid, cmd); } -static bool iface_is_cni(const char *ifname, struct lyd_node *node, const char **type) +static bool iface_is_cni(const char *ifname, struct lyd_node *node, enum iftype *type) { struct lyd_node *net = lydx_get_child(node, "container-network"); if (net) { if (type) - *type = lydx_get_cattr(net, "type"); + *type = iftype_from_iface(net); return true; } @@ -365,9 +366,7 @@ static int iface_gen_cni(const char *ifname, struct lyd_node *cif) * "container-network": {}, so someone does their job. */ if (!type) { - const char *iftype = lydx_get_cattr(cif, "type"); - - if (iftype && !strcmp(iftype, "infix-if-type:bridge")) + if (iftype_from_iface(cif) == IFT_BRIDGE) type = "infix-interfaces:bridge"; else type = "infix-interfaces:host"; @@ -386,7 +385,7 @@ static int iface_gen_cni(const char *ifname, struct lyd_node *cif) int cni_netdag_gen_iface(struct dagger *net, const char *ifname, struct lyd_node *dif, struct lyd_node *cif) { - const char *cni_type = NULL; + enum iftype cni_type; FILE *fp; if (iface_is_cni(ifname, cif, &cni_type)) { @@ -403,7 +402,7 @@ int cni_netdag_gen_iface(struct dagger *net, const char *ifname, err = iface_gen_cni(ifname, cif); if (err) return err; - if (cni_type && !strcmp(cni_type, "bridge")) + if (cni_type == IFT_BRIDGE) return 1; /* CNI bridges are managed by podman */ } else if (iface_is_cni(ifname, dif, &cni_type)) { /* No longer a container-network, clean up. */ @@ -414,7 +413,7 @@ int cni_netdag_gen_iface(struct dagger *net, const char *ifname, fprintf(fp, "container -a -f delete network %s >/dev/null\n", ifname); fclose(fp); - if (cni_type && !strcmp(cni_type, "bridge")) + if (cni_type == IFT_BRIDGE) return 1; /* CNI bridges are managed by podman */ } diff --git a/src/confd/src/ieee802-ethernet-interface.c b/src/confd/src/ieee802-ethernet-interface.c index 699ee051..70285e91 100644 --- a/src/confd/src/ieee802-ethernet-interface.c +++ b/src/confd/src/ieee802-ethernet-interface.c @@ -104,7 +104,6 @@ out: int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node *dif) { struct lyd_node *eth = lydx_get_child(dif, "ethernet"); - const char *type = lydx_get_cattr(cif, "type"); int err; /* @@ -121,7 +120,7 @@ int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node * * Hence this "redundant" check. */ - if (strcmp(type, "infix-if-type:ethernet")) + if (iftype_from_iface(cif) != IFT_ETH) return 0; if (!eth) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 0ecae206..0d3e581a 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -383,58 +383,62 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net, struct lyd_node *cif, FILE *ip) { const char *ifname = lydx_get_cattr(cif, "name"); - const char *iftype = lydx_get_cattr(cif, "type"); - int err = 0; DEBUG_IFACE(dif, ""); - if (!strcmp(iftype, "infix-if-type:bridge")) { - err = bridge_gen(dif, cif, ip, 1); - } else if (!strcmp(iftype, "infix-if-type:dummy")) { - err = netdag_gen_dummy(net, NULL, cif, ip); - } else if (!strcmp(iftype, "infix-if-type:veth")) { - err = netdag_gen_veth(net, NULL, cif, ip); - } else if (!strcmp(iftype, "infix-if-type:vlan")) { - err = netdag_gen_vlan(net, NULL, cif, ip); - } else if (!strcmp(iftype, "infix-if-type:ethernet")) { - sr_session_set_error_message(net->session, "Cannot create fixed Ethernet interface %s," - " wrong type or name.", ifname); - return -ENOENT; - } else if (!strcmp(iftype, "infix-if-type:gre") || !strcmp(iftype, "infix-if-type:gretap")) { - err = gre_gen(net, NULL, cif, ip); - } else if (!strcmp(iftype, "infix-if-type:vxlan")) { - err = vxlan_gen(net, NULL, cif, ip); - } else { - sr_session_set_error_message(net->session, "%s: unsupported interface type \"%s\"", ifname, iftype); + switch (iftype_from_iface(cif)) { + case IFT_BRIDGE: + return bridge_gen(dif, cif, ip, 1); + case IFT_DUMMY: + return netdag_gen_dummy(net, NULL, cif, ip); + case IFT_GRE: + case IFT_GRETAP: + return gre_gen(net, NULL, cif, ip); + case IFT_VETH: + return netdag_gen_veth(net, NULL, cif, ip); + case IFT_VLAN: + return netdag_gen_vlan(net, NULL, cif, ip); + case IFT_VXLAN: + return vxlan_gen(net, NULL, cif, ip); + + case IFT_ETH: + case IFT_ETHISH: + case IFT_UNKNOWN: + sr_session_set_error_message(net->session, "%s: unsupported interface type \"%s\"", + ifname, lydx_get_cattr(cif, "type")); return -ENOSYS; } - if (err) - return err; - - return 0; + __builtin_unreachable(); + return -EINVAL; } static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net, struct lyd_node *dif, struct lyd_node *cif, FILE *ip) { - const char *ifname = lydx_get_cattr(cif, "name"); - const char *iftype = lydx_get_cattr(cif, "type"); - DEBUG_IFACE(dif, ""); - if (!strcmp(iftype, "infix-if-type:bridge")) + switch (iftype_from_iface(cif)) { + case IFT_BRIDGE: return bridge_gen(dif, cif, ip, 0); - if (!strcmp(iftype, "infix-if-type:vlan")) + case IFT_VLAN: return netdag_gen_vlan(net, dif, cif, ip); - if (!strcmp(iftype, "infix-if-type:veth")) + case IFT_GRETAP: + case IFT_VETH: + case IFT_VXLAN: return 0; - if (!strcmp(iftype, "infix-if-type:gretap")) - return 0; - if (!strcmp(iftype, "infix-if-type:vxlan")) - return 0; - ERROR("%s: unsupported interface type \"%s\"", ifname, iftype); - return -ENOSYS; + + case IFT_DUMMY: + case IFT_ETH: + case IFT_ETHISH: + case IFT_GRE: + case IFT_UNKNOWN: + return ERR_IFACE(cif, -ENOSYS, "unsupported interface type \"%s\"", + lydx_get_cattr(cif, "type")); + } + + __builtin_unreachable(); + return -EINVAL; } static bool is_phys_addr_deleted(struct lyd_node *dif) @@ -449,33 +453,28 @@ static bool is_phys_addr_deleted(struct lyd_node *dif) static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif) { - const char *iftype = lydx_get_cattr(cif, "type"); - - if (strcmp(iftype, "infix-if-type:ethernet") && - strcmp(iftype, "infix-if-type:etherlike")) { - if (is_phys_addr_deleted(dif)) - return true; - } - - if (!strcmp(iftype, "infix-if-type:vlan")) { - if (lydx_get_descendant(lyd_child(dif), "vlan", NULL)) - return true; - } else if (!strcmp(iftype, "infix-if-type:veth")) { - if (lydx_get_descendant(lyd_child(dif), "veth", NULL)) - return true; - } else if (!strcmp(iftype, "infix-if-type:gre") || !strcmp(iftype, "infix-if-type:gretap")) { - if (lydx_get_descendant(lyd_child(dif), "gre", NULL)) - return true; - } else if (!strcmp(iftype, "infix-if-type:vxlan")) { - if (lydx_get_descendant(lyd_child(dif), "vxlan", NULL)) - return true; -/* - } else if (!strcmp(iftype, "infix-if-type:lag")) { - if (is_phys_addr_deleted(dif)) - return true; - - ... REMEMBER WHEN ADDING BOND SUPPORT ... -*/ + switch (iftype_from_iface(cif)) { + case IFT_BRIDGE: + case IFT_DUMMY: + break; + case IFT_ETH: + case IFT_ETHISH: + /* case IFT_LAG: */ + /* ... REMEMBER WHEN ADDING BOND SUPPORT ... */ + return is_phys_addr_deleted(dif); + case IFT_GRE: + case IFT_GRETAP: + return lydx_get_descendant(lyd_child(dif), "gre", NULL); + case IFT_VLAN: + return lydx_get_descendant(lyd_child(dif), "vlan", NULL); + case IFT_VETH: + return lydx_get_descendant(lyd_child(dif), "veth", NULL); + case IFT_VXLAN: + return lydx_get_descendant(lyd_child(dif), "vxlan", NULL); + case IFT_UNKNOWN: + ERR_IFACE(cif, -EINVAL, "unsupported interface type \"%s\"", + lydx_get_cattr(cif, "type")); + return true; } return false; @@ -485,7 +484,6 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif, struct lyd_node *cif, bool fixed) { const char *ifname = lydx_get_cattr(dif, "name"); - const char *iftype = lydx_get_cattr(dif, "type"); FILE *ip; DEBUG_IFACE(dif, ""); @@ -493,7 +491,7 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif, if (dagger_should_skip_current(net, ifname)) return 0; - if (iftype && !strcmp(iftype, "infix-if-type:veth")) { + if (iftype_from_iface(cif) == IFT_VETH) { struct lyd_node *node; const char *peer; diff --git a/src/confd/src/ietf-interfaces.h b/src/confd/src/ietf-interfaces.h index fa0b06b4..57c4ef5c 100644 --- a/src/confd/src/ietf-interfaces.h +++ b/src/confd/src/ietf-interfaces.h @@ -21,6 +21,44 @@ #define ONOFF(boolean) boolean ? "on" : "off" +#define IFTYPES(_map) \ + _map(IFT_BRIDGE, "infix-if-type:bridge") \ + _map(IFT_DUMMY, "infix-if-type:dummy") \ + _map(IFT_ETH, "infix-if-type:ethernet") \ + _map(IFT_ETHISH, "infix-if-type:etherlike") \ + _map(IFT_GRE, "infix-if-type:gre") \ + _map(IFT_GRETAP, "infix-if-type:gretap") \ + _map(IFT_VETH, "infix-if-type:veth") \ + _map(IFT_VLAN, "infix-if-type:vlan") \ + _map(IFT_VXLAN, "infix-if-type:vxlan") \ + /* */ + +enum iftype { +#define ift_enum(_enum, _str) _enum, + IFTYPES(ift_enum) +#undef ift_enum + + IFT_UNKNOWN +}; + +static inline enum iftype iftype_from_str(const char *typestr) +{ +#define ift_cmp(_enum, _str) if (!strcmp(typestr, _str)) return _enum; + IFTYPES(ift_cmp) +#undef ift_cmp + return IFT_UNKNOWN; +} + +static inline enum iftype iftype_from_iface(struct lyd_node *ifn) +{ + const char *typestr = lydx_get_cattr(ifn, "type"); + + if (!typestr) + return IFT_UNKNOWN; + + return iftype_from_str(typestr); +} + static inline const char *bridge_tagtype2str(const char *type) { if (!strcmp(type, "ieee802-dot1q-types:c-vlan")) diff --git a/src/confd/src/infix-if-bridge-mcd.c b/src/confd/src/infix-if-bridge-mcd.c index 23c20d8a..c54e4573 100644 --- a/src/confd/src/infix-if-bridge-mcd.c +++ b/src/confd/src/infix-if-bridge-mcd.c @@ -97,7 +97,7 @@ int bridge_mcd_gen(struct lyd_node *cifs) return -EIO; LYX_LIST_FOR_EACH(cifs, cif, "interface") { - if (strcmp(lydx_get_cattr(cif, "type"), "infix-if-type:bridge")) + if (iftype_from_iface(cif) != IFT_BRIDGE) continue; err = gen_bridge(cif, conf); diff --git a/src/confd/src/infix-if-gre.c b/src/confd/src/infix-if-gre.c index 387fc708..3cce6567 100644 --- a/src/confd/src/infix-if-gre.c +++ b/src/confd/src/infix-if-gre.c @@ -6,13 +6,12 @@ int gre_gen(struct dagger *net, struct lyd_node *dif, struct lyd_node *cif, FILE *ip) { - const char *ifname, *iftype, *local, *remote, *mac = NULL; + const char *ifname, *local, *remote, *mac = NULL; struct lyd_node *node = NULL; char gretype[10] = ""; int ipv6; ifname = lydx_get_cattr(cif, "name"); - iftype = lydx_get_cattr(cif, "type"); node = lydx_get_descendant(lyd_child(cif), "gre", NULL); if (!node) @@ -22,13 +21,16 @@ int gre_gen(struct dagger *net, struct lyd_node *dif, remote = lydx_get_cattr(node, "remote"); ipv6 = !!strstr(local, ":"); - if (!strcmp(iftype, "infix-if-type:gre")) { + switch (iftype_from_iface(cif)) { + case IFT_GRE: snprintf(gretype, sizeof(gretype), "%sgre", ipv6 ? "ip6" : ""); - - } - else if (!strcmp(iftype, "infix-if-type:gretap")) { + break; + case IFT_GRETAP: snprintf(gretype, sizeof(gretype), "%sgretap", ipv6 ? "ip6" : ""); mac = get_phys_addr(cif, NULL); + break; + default: + return -EINVAL; } fprintf(ip, "link add name %s type %s local %s remote %s", ifname, gretype, local, remote);