lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <20170511134629.139528-4-fredrik.markstrom@gmail.com> Date: Thu, 11 May 2017 15:46:29 +0200 From: Fredrik Markstrom <fredrik.markstrom@...il.com> To: Eric Dumazet <eric.dumazet@...il.com> Cc: "David S. Miller" <davem@...emloft.net>, Stephen Hemminger <stephen@...workplumber.org>, Alexei Starovoitov <ast@...nel.org>, Daniel Borkmann <daniel@...earbox.net>, netdev@...r.kernel.org, linux-kernel@...r.kernel.org, bridge@...ts.linux-foundation.org, Fredrik Markstrom <fredrik.markstrom@...il.com> Subject: Support for VETH_MRU in libnl --- include/linux/if_link.h | 1 + include/netlink-private/types.h | 1 + include/netlink/route/link/veth.h | 4 ++ lib/route/link.c | 4 ++ lib/route/link/veth.c | 141 +++++++++++++++++++++++++++++--------- 5 files changed, 118 insertions(+), 33 deletions(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 8b84939..b9859bd 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -316,6 +316,7 @@ struct ifla_vxlan_port_range { enum { VETH_INFO_UNSPEC, VETH_INFO_PEER, + VETH_MRU, __VETH_INFO_MAX #define VETH_INFO_MAX (__VETH_INFO_MAX - 1) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 3ff4fe1..c97090b 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -165,6 +165,7 @@ struct rtnl_link uint32_t l_flags; uint32_t l_change; uint32_t l_mtu; + uint32_t l_mru; uint32_t l_link; uint32_t l_txqlen; uint32_t l_weight; diff --git a/include/netlink/route/link/veth.h b/include/netlink/route/link/veth.h index 35c2345..58eeb98 100644 --- a/include/netlink/route/link/veth.h +++ b/include/netlink/route/link/veth.h @@ -29,6 +29,10 @@ extern struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *); extern int rtnl_link_veth_add(struct nl_sock *sock, const char *name, const char *peer, pid_t pid); +extern int rtnl_link_veth_set_mru(struct rtnl_link *, uint32_t); + +extern uint32_t rtnl_link_veth_get_mru(struct rtnl_link *); + #ifdef __cplusplus } #endif diff --git a/lib/route/link.c b/lib/route/link.c index 3d31ffc..3cdacbb 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -61,6 +61,7 @@ #define LINK_ATTR_PHYS_PORT_ID (1 << 28) #define LINK_ATTR_NS_FD (1 << 29) #define LINK_ATTR_NS_PID (1 << 30) +#define LINK_ATTR_MRU (1 << 31) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -1255,6 +1256,9 @@ int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link) if (link->ce_mask & LINK_ATTR_MTU) NLA_PUT_U32(msg, IFLA_MTU, link->l_mtu); + if (link->ce_mask & LINK_ATTR_MRU) + NLA_PUT_U32(msg, IFLA_MTU, link->l_mru); + if (link->ce_mask & LINK_ATTR_TXQLEN) NLA_PUT_U32(msg, IFLA_TXQLEN, link->l_txqlen); diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c index e7e4a26..5dc15af 100644 --- a/lib/route/link/veth.c +++ b/lib/route/link/veth.c @@ -33,16 +33,62 @@ #include <linux/if_link.h> +#define VETH_HAS_MRU (1<<0) + +struct veth_info +{ + struct rtnl_link *peer; + uint32_t vei_mru; + uint32_t vei_mask; +}; + static struct nla_policy veth_policy[VETH_INFO_MAX+1] = { [VETH_INFO_PEER] = { .minlen = sizeof(struct ifinfomsg) }, + [VETH_MRU] = { .type = NLA_U32 }, }; +static int veth_alloc(struct rtnl_link *link) +{ + struct rtnl_link *peer; + struct veth_info *vei = link->l_info; + int err; + + /* return early if we are in recursion */ + if (vei && vei->peer) + return 0; + + if (!(peer = rtnl_link_alloc())) + return -NLE_NOMEM; + + if ((vei = calloc(1, sizeof(*vei))) == NULL) + return -NLE_NOMEM; + + /* We don't need to hold a reference here, as link and + * its peer should always be freed together. + */ + vei->peer = link; + + peer->l_info = vei; + if ((err = rtnl_link_set_type(peer, "veth")) < 0) { + rtnl_link_put(peer); + return err; + } + + if ((vei = calloc(1, sizeof(*vei))) == NULL) + return -NLE_NOMEM; + + vei->peer = peer; + link->l_info = vei; + return 0; +} + static int veth_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[VETH_INFO_MAX+1]; struct nlattr *peer_tb[IFLA_MAX + 1]; - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; int err; NL_DBG(3, "Parsing veth link info"); @@ -50,6 +96,14 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data, if ((err = nla_parse_nested(tb, VETH_INFO_MAX, data, veth_policy)) < 0) goto errout; + if ((err = veth_alloc(link)) < 0) + goto errout; + + if (tb[VETH_MRU]) { + vei->vei_mru = nla_get_u32(tb[VETH_MRU]); + vei->vei_mask |= VETH_HAS_MRU; + } + if (tb[VETH_INFO_PEER]) { struct nlattr *nla_peer; struct ifinfomsg *ifi; @@ -86,7 +140,8 @@ static void veth_dump_line(struct rtnl_link *link, struct nl_dump_params *p) static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; char *name; name = rtnl_link_get_name(peer); nl_dump(p, " peer "); @@ -98,7 +153,14 @@ static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p) static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src) { - struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info; + struct veth_info *src_vei = src->l_info; + struct veth_info *dst_vei = dst->l_info; + struct rtnl_link *dst_peer = NULL, *src_peer = src_vei->peer; + + + printf("veth_clone not implemented\n"); + + // FIXME: /* we are calling nl_object_clone() recursively, this should * happen only once */ @@ -116,7 +178,8 @@ static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src) static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; struct ifinfomsg ifi; struct nlattr *data, *info_peer; @@ -135,44 +198,31 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link) return -NLE_MSGSIZE; rtnl_link_fill_info(msg, peer); nla_nest_end(msg, info_peer); - nla_nest_end(msg, data); - return 0; -} - -static int veth_alloc(struct rtnl_link *link) -{ - struct rtnl_link *peer; - int err; - - /* return early if we are in recursion */ - if (link->l_info) - return 0; + if (vei->vei_mask & VETH_HAS_MRU) + NLA_PUT_U32(msg, VETH_MRU, vei->vei_mru); - if (!(peer = rtnl_link_alloc())) - return -NLE_NOMEM; + nla_nest_end(msg, data); - /* We don't need to hold a reference here, as link and - * its peer should always be freed together. - */ - peer->l_info = link; - if ((err = rtnl_link_set_type(peer, "veth")) < 0) { - rtnl_link_put(peer); - return err; - } +nla_put_failure: - link->l_info = peer; return 0; } static void veth_free(struct rtnl_link *link) { - struct rtnl_link *peer = link->l_info; - if (peer) { + struct veth_info *vei = link->l_info; + if (vei) { + struct rtnl_link *peer = vei->peer; + if (peer) { + vei->peer = NULL; + rtnl_link_put(peer); + /* avoid calling this recursively */ + free(peer->l_info); + peer->l_info = NULL; + } + free(vei); link->l_info = NULL; - /* avoid calling this recursively */ - peer->l_info = NULL; - rtnl_link_put(peer); } /* the caller should finally free link */ } @@ -195,7 +245,7 @@ static struct rtnl_link_info_ops veth_info_ops = { #define IS_VETH_LINK_ASSERT(link) \ if ((link)->l_info_ops != &veth_info_ops) { \ APPBUG("Link is not a veth link. set type \"veth\" first."); \ - return NULL; \ + return -NLE_OPNOTSUPP; \ } /** @endcond */ @@ -293,6 +343,31 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name, return err; } +int rtnl_link_veth_set_mru(struct rtnl_link *link, uint32_t mru) +{ + struct veth_info *vei = link->l_info; + + IS_VETH_LINK_ASSERT(link); + + vei->vei_mru = mru; + vei->vei_mask |= VETH_HAS_MRU; + + return 0; +} + +uint32_t rtnl_link_veth_get_mru(struct rtnl_link *link) +{ + struct veth_info *vei = link->l_info; + + IS_VETH_LINK_ASSERT(link); + + if (vei->vei_mask & VETH_HAS_MRU) + return vei->vei_mru; + else + return 0; +} + + /** @} */ static void __init veth_init(void) -- 2.10.1
Powered by blists - more mailing lists