diff options
author | Susant Sahani <ssahani@vmware.com> | 2021-05-14 14:28:18 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-20 18:23:15 +0900 |
commit | af99cdf4d493c2e97bc789e22336c377dad1c6e9 (patch) | |
tree | 92f6a8de2f44aefbcfc15e4a239e0197f6f39313 /src/network/networkd-bridge-fdb.c | |
parent | e5b35bf6c28a0c63dff452ebe12917b716255b62 (diff) | |
download | systemd-af99cdf4d493c2e97bc789e22336c377dad1c6e9.tar.gz |
network: bridge-fdb: add support to specify outgoing interface
Diffstat (limited to 'src/network/networkd-bridge-fdb.c')
-rw-r--r-- | src/network/networkd-bridge-fdb.c | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/src/network/networkd-bridge-fdb.c b/src/network/networkd-bridge-fdb.c index 8000d0ffe4..115ea5bb14 100644 --- a/src/network/networkd-bridge-fdb.c +++ b/src/network/networkd-bridge-fdb.c @@ -33,6 +33,8 @@ BridgeFDB *bridge_fdb_free(BridgeFDB *fdb) { } network_config_section_free(fdb->section); + + free(fdb->outgoing_ifname); return mfree(fdb); } @@ -154,6 +156,12 @@ static int bridge_fdb_configure(const BridgeFDB *fdb, Link *link, link_netlink_m return log_link_error_errno(link, r, "Could not append NDA_VLAN attribute: %m"); } + if (fdb->outgoing_ifindex > 0) { + r = sd_netlink_message_append_u32(req, NDA_IFINDEX, fdb->outgoing_ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not append NDA_IFINDEX attribute: %m"); + } + if (in_addr_is_set(fdb->family, &fdb->destination_addr)) { r = netlink_message_append_in_addr_union(req, NDA_DST, fdb->family, &fdb->destination_addr); if (r < 0) @@ -204,13 +212,38 @@ int link_request_static_bridge_fdb(Link *link) { return 0; } +static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) { + Link *out = NULL; + + assert(fdb); + assert(link); + assert(link->manager); + + if (!link_is_ready_to_configure(link, false)) + return false; + + if (fdb->outgoing_ifname) { + if (link_get_by_name(link->manager, fdb->outgoing_ifname, &out) < 0) + return false; + + fdb->outgoing_ifindex = out->ifindex; + } else if (fdb->outgoing_ifindex > 0) { + if (link_get(link->manager, fdb->outgoing_ifindex, &out) < 0) + return false; + } + if (out && !link_is_ready_to_configure(out, false)) + return false; + + return true; +} + int request_process_bridge_fdb(Request *req) { assert(req); assert(req->link); assert(req->fdb); assert(req->type == REQUEST_TYPE_BRIDGE_FDB); - if (!link_is_ready_to_configure(req->link, false)) + if (!bridge_fdb_is_ready_to_configure(req->fdb, req->link)) return 0; return bridge_fdb_configure(req->fdb, req->link, req->netlink_handler); @@ -435,3 +468,59 @@ int config_parse_fdb_ntf_flags( TAKE_PTR(fdb); return 0; } + +int config_parse_fdb_interface( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(bridge_fdb_free_or_set_invalidp) BridgeFDB *fdb = NULL; + Network *network = userdata; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = bridge_fdb_new_static(network, filename, section_line, &fdb); + if (r < 0) + return log_oom(); + + if (isempty(rvalue)) { + fdb->outgoing_ifname = mfree(fdb->outgoing_ifname); + fdb->outgoing_ifindex = 0; + TAKE_PTR(fdb); + return 0; + } + + r = parse_ifindex(rvalue); + if (r > 0) { + fdb->outgoing_ifname = mfree(fdb->outgoing_ifname); + fdb->outgoing_ifindex = r; + TAKE_PTR(fdb); + return 0; + } + + if (!ifname_valid_full(rvalue, IFNAME_VALID_ALTERNATIVE)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid interface name in %s=, ignoring assignment: %s", lvalue, rvalue); + return 0; + } + + r = free_and_strdup(&fdb->outgoing_ifname, rvalue); + if (r < 0) + return log_oom(); + fdb->outgoing_ifindex = 0; + + TAKE_PTR(fdb); + return 0; +} |