summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNobuhiro MIKI <nmiki@yahoo-corp.jp>2023-03-06 11:49:15 +0900
committerIlya Maximets <i.maximets@ovn.org>2023-03-07 18:22:40 +0100
commitde6589799e7e810d5ff243b7b00fd2af5bf99ff2 (patch)
tree4dafa3d75e545e041fd01b682340e101771c1a28 /lib
parentf65d1951dfd06be469111c754d35890f7491bc5d (diff)
downloadopenvswitch-de6589799e7e810d5ff243b7b00fd2af5bf99ff2.tar.gz
netdev-dummy: Support multiple IP addresses.
This is useful in test cases where multiple IPv4/IPv6 addresses are assigned together. Acked-by: Eelco Chaudron <echaudro@redhat.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: Nobuhiro MIKI <nmiki@yahoo-corp.jp> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/netdev-dummy.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 5d59c9c03..7467e9fbc 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -136,8 +136,7 @@ struct netdev_dummy {
struct pcap_file *tx_pcap, *rxq_pcap OVS_GUARDED;
- struct in_addr address, netmask;
- struct in6_addr ipv6, ipv6_mask;
+ struct ovs_list addrs OVS_GUARDED;
struct ovs_list rxes OVS_GUARDED; /* List of child "netdev_rxq_dummy"s. */
struct hmap offloaded_flows OVS_GUARDED;
@@ -161,6 +160,12 @@ struct netdev_rxq_dummy {
struct seq *seq; /* Reports newly queued packets. */
};
+struct netdev_addr_dummy {
+ struct in6_addr address;
+ struct in6_addr netmask;
+ struct ovs_list node; /* In netdev_dummy's "addrs" list. */
+};
+
static unixctl_cb_func netdev_dummy_set_admin_state;
static int netdev_dummy_construct(struct netdev *);
static void netdev_dummy_queue_packet(struct netdev_dummy *,
@@ -169,6 +174,7 @@ static void netdev_dummy_queue_packet(struct netdev_dummy *,
static void dummy_packet_stream_close(struct dummy_packet_stream *);
static void pkt_list_delete(struct ovs_list *);
+static void addr_list_delete(struct ovs_list *);
static bool
is_dummy_class(const struct netdev_class *class)
@@ -720,6 +726,7 @@ netdev_dummy_construct(struct netdev *netdev_)
dummy_packet_conn_init(&netdev->conn);
ovs_list_init(&netdev->rxes);
+ ovs_list_init(&netdev->addrs);
hmap_init(&netdev->offloaded_flows);
ovs_mutex_unlock(&netdev->mutex);
@@ -756,6 +763,7 @@ netdev_dummy_destruct(struct netdev *netdev_)
free(off_flow);
}
hmap_destroy(&netdev->offloaded_flows);
+ addr_list_delete(&netdev->addrs);
ovs_mutex_unlock(&netdev->mutex);
ovs_mutex_destroy(&netdev->mutex);
@@ -803,32 +811,24 @@ netdev_dummy_get_addr_list(const struct netdev *netdev_, struct in6_addr **paddr
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
int cnt = 0, i = 0, err = 0;
struct in6_addr *addr, *mask;
+ struct netdev_addr_dummy *addr_dummy;
ovs_mutex_lock(&netdev->mutex);
- if (netdev->address.s_addr != INADDR_ANY) {
- cnt++;
- }
- if (ipv6_addr_is_set(&netdev->ipv6)) {
- cnt++;
- }
+ cnt = ovs_list_size(&netdev->addrs);
if (!cnt) {
err = EADDRNOTAVAIL;
goto out;
}
addr = xmalloc(sizeof *addr * cnt);
mask = xmalloc(sizeof *mask * cnt);
- if (netdev->address.s_addr != INADDR_ANY) {
- in6_addr_set_mapped_ipv4(&addr[i], netdev->address.s_addr);
- in6_addr_set_mapped_ipv4(&mask[i], netdev->netmask.s_addr);
- i++;
- }
- if (ipv6_addr_is_set(&netdev->ipv6)) {
- memcpy(&addr[i], &netdev->ipv6, sizeof *addr);
- memcpy(&mask[i], &netdev->ipv6_mask, sizeof *mask);
+ LIST_FOR_EACH (addr_dummy, node, &netdev->addrs) {
+ memcpy(&addr[i], &addr_dummy->address, sizeof *addr);
+ memcpy(&mask[i], &addr_dummy->netmask, sizeof *mask);
i++;
}
+
if (paddr) {
*paddr = addr;
*pmask = mask;
@@ -844,14 +844,16 @@ out:
}
static int
-netdev_dummy_set_in4(struct netdev *netdev_, struct in_addr address,
+netdev_dummy_add_in4(struct netdev *netdev_, struct in_addr address,
struct in_addr netmask)
{
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+ struct netdev_addr_dummy *addr_dummy = xmalloc(sizeof *addr_dummy);
ovs_mutex_lock(&netdev->mutex);
- netdev->address = address;
- netdev->netmask = netmask;
+ in6_addr_set_mapped_ipv4(&addr_dummy->address, address.s_addr);
+ in6_addr_set_mapped_ipv4(&addr_dummy->netmask, netmask.s_addr);
+ ovs_list_push_back(&netdev->addrs, &addr_dummy->node);
netdev_change_seq_changed(netdev_);
ovs_mutex_unlock(&netdev->mutex);
@@ -859,14 +861,16 @@ netdev_dummy_set_in4(struct netdev *netdev_, struct in_addr address,
}
static int
-netdev_dummy_set_in6(struct netdev *netdev_, struct in6_addr *in6,
+netdev_dummy_add_in6(struct netdev *netdev_, struct in6_addr *in6,
struct in6_addr *mask)
{
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+ struct netdev_addr_dummy *addr_dummy = xmalloc(sizeof *addr_dummy);
ovs_mutex_lock(&netdev->mutex);
- netdev->ipv6 = *in6;
- netdev->ipv6_mask = *mask;
+ addr_dummy->address = *in6;
+ addr_dummy->netmask = *mask;
+ ovs_list_push_back(&netdev->addrs, &addr_dummy->node);
netdev_change_seq_changed(netdev_);
ovs_mutex_unlock(&netdev->mutex);
@@ -1178,7 +1182,10 @@ netdev_dummy_send(struct netdev *netdev, int qid,
dummy_packet_conn_send(&dev->conn, buffer, size);
/* Reply to ARP requests for 'dev''s assigned IP address. */
- if (dev->address.s_addr) {
+ struct netdev_addr_dummy *addr_dummy;
+ LIST_FOR_EACH (addr_dummy, node, &dev->addrs) {
+ ovs_be32 address = in6_addr_get_mapped_ipv4(&addr_dummy->address);
+
struct dp_packet dp;
struct flow flow;
@@ -1186,11 +1193,12 @@ netdev_dummy_send(struct netdev *netdev, int qid,
flow_extract(&dp, &flow);
if (flow.dl_type == htons(ETH_TYPE_ARP)
&& flow.nw_proto == ARP_OP_REQUEST
- && flow.nw_dst == dev->address.s_addr) {
+ && flow.nw_dst == address) {
struct dp_packet *reply = dp_packet_new(0);
compose_arp(reply, ARP_OP_REPLY, dev->hwaddr, flow.dl_src,
false, flow.nw_dst, flow.nw_src);
netdev_dummy_queue_packet(dev, reply, NULL, 0);
+ break;
}
}
@@ -1677,6 +1685,16 @@ pkt_list_delete(struct ovs_list *l)
}
}
+static void
+addr_list_delete(struct ovs_list *l)
+{
+ struct netdev_addr_dummy *addr_dummy;
+
+ LIST_FOR_EACH_POP (addr_dummy, node, l) {
+ free(addr_dummy);
+ }
+}
+
static struct dp_packet *
eth_from_packet(const char *s)
{
@@ -2009,7 +2027,7 @@ netdev_dummy_ip4addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
error = ip_parse_masked(argv[2], &ip.s_addr, &mask.s_addr);
if (!error) {
- netdev_dummy_set_in4(netdev, ip, mask);
+ netdev_dummy_add_in4(netdev, ip, mask);
unixctl_command_reply(conn, "OK");
} else {
unixctl_command_reply_error(conn, error);
@@ -2038,7 +2056,7 @@ netdev_dummy_ip6addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
struct in6_addr mask;
mask = ipv6_create_mask(plen);
- netdev_dummy_set_in6(netdev, &ip6, &mask);
+ netdev_dummy_add_in6(netdev, &ip6, &mask);
unixctl_command_reply(conn, "OK");
} else {
unixctl_command_reply_error(conn, error);