mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
confd: Create an enumerator for interface types
This has multiple advantages: - Less chances of typos is repeated "infix-if-type:foo" strings scattered throughout the code - We can lean on GCC's `-Werror=switch` to make sure that iface specific logic always handles all types (which was not always the case - see follow-up commits) - We can potentially create a `struct afspec_ops` in the future, which could then be indexed by this enum
This commit is contained in:
+7
-8
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user