Path: blob/main/tests/sys/netlink/test_rtnl_gre.c
178478 views
/*1* Copyright (c) 2026 Pouria Mousavizadeh Tehrani <[email protected]>2*3* SPDX-License-Identifier: BSD-2-Clause4*/56#include <sys/param.h>7#include <sys/module.h>8#include <sys/types.h>9#include <sys/socket.h>10#include <netinet/in.h>11#include <arpa/inet.h>12#include <net/if_gre.h>1314#include <netlink/netlink.h>15#include <netlink/netlink_route.h>16#include "netlink/netlink_snl.h"17#include <netlink/netlink_snl_route.h>18#include <netlink/netlink_snl_route_compat.h>19#include <netlink/netlink_snl_route_parsers.h>2021#include <atf-c.h>2223struct nl_parsed_gre {24struct sockaddr *ifla_local;25struct sockaddr *ifla_remote;26uint32_t ifla_flags;27uint32_t ifla_okey;28uint32_t ifla_encap_type;29uint16_t ifla_encap_sport;30};3132struct nla_gre_info {33const char *kind;34struct nl_parsed_gre data;35};3637struct nla_gre_link {38uint32_t ifi_index;39struct nla_gre_info linkinfo;40};4142#define _OUT(_field) offsetof(struct nl_parsed_gre, _field)43static const struct snl_attr_parser nla_p_gre[] = {44{ .type = IFLA_GRE_LOCAL, .off = _OUT(ifla_local), .cb = snl_attr_get_ip },45{ .type = IFLA_GRE_REMOTE, .off = _OUT(ifla_remote), .cb = snl_attr_get_ip },46{ .type = IFLA_GRE_FLAGS, .off = _OUT(ifla_flags), .cb = snl_attr_get_uint32 },47{ .type = IFLA_GRE_OKEY, .off = _OUT(ifla_okey), .cb = snl_attr_get_uint32 },48{ .type = IFLA_GRE_ENCAP_TYPE, .off = _OUT(ifla_encap_type), .cb = snl_attr_get_uint32 },49{ .type = IFLA_GRE_ENCAP_SPORT, .off = _OUT(ifla_encap_sport), .cb = snl_attr_get_uint16 },50};51#undef _OUT52SNL_DECLARE_ATTR_PARSER(gre_linkinfo_data_parser, nla_p_gre);5354#define _OUT(_field) offsetof(struct nla_gre_info, _field)55static const struct snl_attr_parser ap_gre_linkinfo[] = {56{ .type = IFLA_INFO_KIND, .off = _OUT(kind), .cb = snl_attr_get_string },57{ .type = IFLA_INFO_DATA, .off = _OUT(data),58.arg = &gre_linkinfo_data_parser, .cb = snl_attr_get_nested },59};60#undef _OUT61SNL_DECLARE_ATTR_PARSER(gre_linkinfo_parser, ap_gre_linkinfo);6263#define _IN(_field) offsetof(struct ifinfomsg, _field)64#define _OUT(_field) offsetof(struct nla_gre_link, _field)65static const struct snl_attr_parser ap_gre_link[] = {66{ .type = IFLA_LINKINFO, .off = _OUT(linkinfo),67.arg = &gre_linkinfo_parser, .cb = snl_attr_get_nested },68};6970static const struct snl_field_parser fp_gre_link[] = {71{ .off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 },72};73#undef _IN74#undef _OUT75SNL_DECLARE_PARSER(gre_parser, struct ifinfomsg, fp_gre_link, ap_gre_link);7677ATF_TC(test_rtnl_gre);78ATF_TC_HEAD(test_rtnl_gre, tc)79{80atf_tc_set_md_var(tc, "descr", "test gre interface using netlink");81atf_tc_set_md_var(tc, "require.user", "root");82atf_tc_set_md_var(tc, "require.kmods", "netlink if_gre");83}8485ATF_TC_BODY(test_rtnl_gre, tc)86{87struct snl_state ss;88struct snl_writer nw;89struct nlmsghdr *hdr, *rx_hdr;90struct in_addr src, dst;91struct nla_gre_link lattrs = {};92struct nl_parsed_gre attrs = {};93struct snl_errmsg_data e = {};94struct ifinfomsg *ifmsg;95int off, off2;9697ATF_REQUIRE_MSG(snl_init(&ss, NETLINK_ROUTE), "snl_init() failed");9899/* Create gre interface */100snl_init_writer(&ss, &nw);101ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWLINK)) != NULL);102hdr->nlmsg_flags |= (NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST | NLM_F_ACK);103snl_reserve_msg_object(&nw, struct ifinfomsg);104105/* Create parameters */106snl_add_msg_attr_string(&nw, IFLA_IFNAME, "gre10");107off = snl_add_msg_attr_nested(&nw, IFLA_LINKINFO);108snl_add_msg_attr_string(&nw, IFLA_INFO_KIND, "gre");109off2 = snl_add_msg_attr_nested(&nw, IFLA_INFO_DATA);110111inet_pton(AF_INET, "127.0.0.1", &src);112inet_pton(AF_INET, "127.0.0.2", &dst);113snl_add_msg_attr_ip4(&nw, IFLA_GRE_LOCAL, &src);114snl_add_msg_attr_ip4(&nw, IFLA_GRE_REMOTE, &dst);115snl_add_msg_attr_u32(&nw, IFLA_GRE_FLAGS, (GRE_ENABLE_SEQ | GRE_ENABLE_CSUM));116snl_add_msg_attr_u32(&nw, IFLA_GRE_OKEY, 123456);117snl_add_msg_attr_u32(&nw, IFLA_GRE_ENCAP_TYPE, IFLA_TUNNEL_GRE_UDP);118snl_add_msg_attr_u16(&nw, IFLA_GRE_ENCAP_SPORT, 50000);119120snl_end_attr_nested(&nw, off2);121snl_end_attr_nested(&nw, off);122123ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);124ATF_REQUIRE(snl_send_message(&ss, hdr));125ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);126ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e));127ATF_REQUIRE_INTEQ(e.error, 0);128129/* Dump gre interface */130snl_init_writer(&ss, &nw);131ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETLINK)) != NULL);132hdr->nlmsg_flags |= NLM_F_DUMP;133snl_reserve_msg_object(&nw, struct ifinfomsg);134snl_add_msg_attr_string(&nw, IFLA_IFNAME, "gre10");135off = snl_add_msg_attr_nested(&nw, IFLA_LINKINFO);136snl_add_msg_attr_string(&nw, IFLA_INFO_KIND, "gre");137snl_end_attr_nested(&nw, off);138139ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);140ATF_REQUIRE(snl_send_message(&ss, hdr));141142/* Check parameters */143ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);144ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &gre_parser, &lattrs));145attrs = lattrs.linkinfo.data;146ATF_CHECK_STREQ(lattrs.linkinfo.kind, "gre");147ATF_CHECK_INTEQ(attrs.ifla_flags, (GRE_ENABLE_SEQ | GRE_ENABLE_CSUM | GRE_UDPENCAP));148ATF_CHECK_INTEQ(attrs.ifla_okey, 123456);149ATF_CHECK_INTEQ(attrs.ifla_encap_type, IFLA_TUNNEL_GRE_UDP);150ATF_CHECK_INTEQ(attrs.ifla_encap_sport, 50000);151152/* Delete gre interface */153snl_init_writer(&ss, &nw);154ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_DELLINK)) != NULL);155hdr->nlmsg_flags |= (NLM_F_ACK | NLM_F_REQUEST);156ATF_REQUIRE((ifmsg = snl_reserve_msg_object(&nw, struct ifinfomsg)) != NULL);157ifmsg->ifi_index = lattrs.ifi_index;158ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);159ATF_REQUIRE(snl_send_message(&ss, hdr));160ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);161ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e));162ATF_REQUIRE_INTEQ(e.error, 0);163}164165ATF_TP_ADD_TCS(tp)166{167ATF_TP_ADD_TC(tp, test_rtnl_gre);168169return (atf_no_error());170}171172173174