From: Petr Vorel <pvorel@suse.cz>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v5 2/2] net/route: Add netlink based route change tests
Date: Wed, 29 Apr 2020 12:41:29 +0200 [thread overview]
Message-ID: <20200429104129.GA685@dell5510> (raw)
In-Reply-To: <8b3ae56d-1c28-e43b-abea-963a32fff8f6@oracle.com>
Hi Alexey,
> Minor comments below.
Thanks for your review!
> > + for (i = 0; i < num_loops; i++) {
> > + if (iface_len > 1)
> > + tst_res(TINFO, "testing gw: %s, iface: %s",
> > + p_gw->ip_str, p_iface->iface);
> > + else if (gw_len > 1)
> > + tst_res(TINFO, "testing gw: %s", p_gw->ip_str);
> > + else
> > + tst_res(TINFO, "testing dst: %s/%d", p_dst->ip_str, prefix);
> It would be better to avoid printing it on every iteration, especially
> with the large NS_TIMES.
Understand, I thought you wouldn't like it. How about print only on error?
> > +
> > + rtnl_route(p_iface->index, p_dst->ip, gw ? p_gw->ip : NULL,
> > + prefix, RTM_NEWROUTE);
> > + send_udp(p_rhost->ip);
> > + rtnl_route(p_iface->index, p_dst->ip, gw ? p_gw->ip : NULL,
> > + prefix, RTM_DELROUTE);
> > +
> > + if (gw)
> > + p_gw = p_gw->next ?: gw;
> > + p_dst = p_dst->next ?: dst;
> > + p_iface = p_iface->next ?: iface;
> > + p_rhost = p_rhost->next ?: rhost;
> > + }
> > +
> > + tst_res(TPASS, "routes created and deleted");
> > +}
Something like this?
static void print_route_info(int iface, struct sockaddr *dst,
struct sockaddr *gw, int type)
{
char dst_str[INET6_ADDRSTRLEN], gw_str[INET6_ADDRSTRLEN];
tst_sock_addr(dst, sizeof(dst), dst_str, sizeof(dst_str));
if (gw)
tst_sock_addr(gw, sizeof(gw), gw_str, sizeof(gw_str));
tst_res(TINFO, "type: %s, iface: %d, dst: %s, gw: %s",
type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
iface, dst_str, gw ? gw_str : "null");
tst_brk(TBROK, "failed due previous netlink errors");
}
static void rtnl_route(int iface, struct addrinfo *dst, struct addrinfo *gw,
int type)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct rtmsg *rtm;
uint32_t seq, portid;
struct in6_addr dst_in6, gw_in6;
in_addr_t dst_ip, gw_ip;
int ret;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = type;
nlh->nlmsg_flags = NLM_F_ACK;
if (type == RTM_NEWROUTE)
nlh->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE;
nlh->nlmsg_seq = seq = time(NULL);
rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
rtm->rtm_family = family;
rtm->rtm_dst_len = prefix;
rtm->rtm_src_len = 0;
rtm->rtm_tos = 0;
rtm->rtm_protocol = RTPROT_STATIC;
rtm->rtm_table = RT_TABLE_MAIN;
rtm->rtm_type = RTN_UNICAST;
rtm->rtm_scope = gw ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
rtm->rtm_flags = 0;
if (is_ipv6) {
dst_in6 = ((struct sockaddr_in6 *)dst->ai_addr)->sin6_addr;
mnl_attr_put(nlh, RTA_DST, sizeof(struct in6_addr), &dst_in6);
} else {
dst_ip = ((struct sockaddr_in *)dst->ai_addr)->sin_addr.s_addr;
mnl_attr_put_u32(nlh, RTA_DST, dst_ip);
}
mnl_attr_put_u32(nlh, RTA_OIF, iface);
if (gw) {
if (is_ipv6) {
gw_in6 = ((struct sockaddr_in6 *)gw->ai_addr)->sin6_addr;
mnl_attr_put(nlh, RTA_GATEWAY, sizeof(struct in6_addr), &gw_in6);
} else {
gw_ip = ((struct sockaddr_in *)gw->ai_addr)->sin_addr.s_addr;
mnl_attr_put_u32(nlh, RTA_GATEWAY, gw_ip);
}
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
tst_res(TFAIL, "mnl_socket_open failed (errno=%d): %s", errno,
strerror(errno));
goto err;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
tst_res(TFAIL, "mnl_socket_bind failed (errno=%d): %s", errno,
strerror(errno));
goto err;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
tst_res(TFAIL, "mnl_socket_sendto failed (errno=%d): %s", errno,
strerror(errno));
goto err;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret < 0) {
tst_res(TFAIL, "mnl_socket_recvfrom failed (ret=%d, errno=%d): %s",
ret, errno, strerror(errno));
goto err;
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret < 0) {
tst_res(TFAIL, "mnl_cb_run failed (ret=%d, errno=%d): %s", ret,
errno, strerror(errno));
goto err;
}
mnl_socket_close(nl);
return;
err:
print_route_info(iface, dst->ai_addr, gw ? gw->ai_addr: NULL, type);
}
> > +
> > +static struct tst_option options[] = {
> > + {"6", &ipv6_opt, "-6 Use IPv6 (default is IPv4)"},
> > + {"c:", &c_opt, " Num loops (mandatory)"},
> "-c x ...
Fixed.
BTW I also removed prefix parameter from rtnl_route() (it's a global parameter,
family is not passed either).
https://github.com/pevik/ltp/blob/route/c.v5.fixes/testcases/network/stress/route/route-change-netlink.c
+ below is full diff against posted version.
Kind regards,
Petr
diff --git testcases/network/stress/route/route-change-netlink.c testcases/network/stress/route/route-change-netlink.c
index 57ae02a3c..80677f1a4 100644
--- testcases/network/stress/route/route-change-netlink.c
+++ testcases/network/stress/route/route-change-netlink.c
@@ -177,7 +177,22 @@ static void cleanup(void)
mnl_socket_close(nl);
}
-static void rtnl_route(int iface, struct addrinfo *dst, struct addrinfo *gw, uint32_t prefix, int type)
+static void print_route_info(int iface, struct sockaddr *dst,
+ struct sockaddr *gw, int type)
+{
+ char dst_str[INET6_ADDRSTRLEN], gw_str[INET6_ADDRSTRLEN];
+ tst_sock_addr(dst, sizeof(dst), dst_str, sizeof(dst_str));
+ if (gw)
+ tst_sock_addr(gw, sizeof(gw), gw_str, sizeof(gw_str));
+
+ tst_res(TINFO, "type: %s, iface: %d, dst: %s, gw: %s",
+ type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
+ iface, dst_str, gw ? gw_str : "null");
+ tst_brk(TBROK, "failed due previous netlink errors");
+}
+
+static void rtnl_route(int iface, struct addrinfo *dst, struct addrinfo *gw,
+ int type)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -229,31 +244,44 @@ static void rtnl_route(int iface, struct addrinfo *dst, struct addrinfo *gw, uin
}
nl = mnl_socket_open(NETLINK_ROUTE);
- if (nl == NULL)
- tst_brk(TBROK, "mnl_socket_open failed (errno=%d): %s", errno,
+ if (nl == NULL) {
+ tst_res(TFAIL, "mnl_socket_open failed (errno=%d): %s", errno,
strerror(errno));
+ goto err;
+ }
- if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
- tst_brk(TBROK, "mnl_socket_bind failed (errno=%d): %s", errno,
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ tst_res(TFAIL, "mnl_socket_bind failed (errno=%d): %s", errno,
strerror(errno));
+ goto err;
+ }
portid = mnl_socket_get_portid(nl);
- if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
- tst_brk(TBROK, "mnl_socket_sendto failed (errno=%d): %s", errno,
+ if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
+ tst_res(TFAIL, "mnl_socket_sendto failed (errno=%d): %s", errno,
strerror(errno));
+ goto err;
+ }
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- if (ret < 0)
- tst_brk(TBROK, "mnl_socket_recvfrom failed (ret=%d, errno=%d): %s",
+ if (ret < 0) {
+ tst_res(TFAIL, "mnl_socket_recvfrom failed (ret=%d, errno=%d): %s",
ret, errno, strerror(errno));
+ goto err;
+ }
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
- if (ret < 0)
- tst_brk(TBROK, "mnl_cb_run failed (ret=%d, errno=%d): %s", ret,
+ if (ret < 0) {
+ tst_res(TFAIL, "mnl_cb_run failed (ret=%d, errno=%d): %s", ret,
errno, strerror(errno));
+ goto err;
+ }
mnl_socket_close(nl);
+ return;
+err:
+ print_route_info(iface, dst->ai_addr, gw ? gw->ai_addr: NULL, type);
}
static void send_udp(struct addrinfo *rhost_addrinfo)
@@ -274,19 +302,11 @@ static void run(void)
struct iface *p_iface = iface;
for (i = 0; i < num_loops; i++) {
- if (iface_len > 1)
- tst_res(TINFO, "testing gw: %s, iface: %s",
- p_gw->ip_str, p_iface->iface);
- else if (gw_len > 1)
- tst_res(TINFO, "testing gw: %s", p_gw->ip_str);
- else
- tst_res(TINFO, "testing dst: %s/%d", p_dst->ip_str, prefix);
-
rtnl_route(p_iface->index, p_dst->ip, gw ? p_gw->ip : NULL,
- prefix, RTM_NEWROUTE);
+ RTM_NEWROUTE);
send_udp(p_rhost->ip);
rtnl_route(p_iface->index, p_dst->ip, gw ? p_gw->ip : NULL,
- prefix, RTM_DELROUTE);
+ RTM_DELROUTE);
if (gw)
p_gw = p_gw->next ?: gw;
@@ -300,7 +320,7 @@ static void run(void)
static struct tst_option options[] = {
{"6", &ipv6_opt, "-6 Use IPv6 (default is IPv4)"},
- {"c:", &c_opt, " Num loops (mandatory)"},
+ {"c:", &c_opt, "-c x Num loops (mandatory)"},
{"d:", &d_opt, "-d iface Interface to work on (mandatory)"},
{"g:", &g_opt, "-g x Gateway IP"},
{"p:", &p_opt, "-p port Rhost port (mandatory)"},
next prev parent reply other threads:[~2020-04-29 10:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-23 13:16 [LTP] [PATCH v5 0/2] Route tests using netlink API (dst,gw,if) Petr Vorel
2020-04-23 13:16 ` [LTP] [PATCH v5 1/2] net: Add SAFE_GETADDRINFO() Petr Vorel
2020-04-28 16:09 ` Alexey Kodanev
2020-04-23 13:16 ` [LTP] [PATCH v5 2/2] net/route: Add netlink based route change tests Petr Vorel
2020-04-28 16:54 ` Alexey Kodanev
2020-04-29 10:41 ` Petr Vorel [this message]
2020-04-29 17:04 ` Alexey Kodanev
2020-04-29 18:47 ` Petr Vorel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200429104129.GA685@dell5510 \
--to=pvorel@suse.cz \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.