networkd: add support for vxlan Remote and Local.
authorSusant Sahani <susant@redhat.com>
Fri, 24 Feb 2017 19:01:47 +0000 (00:31 +0530)
committerSusant Sahani <susant@redhat.com>
Fri, 24 Feb 2017 19:01:47 +0000 (00:31 +0530)
This patch add supports to configure IFLA_VXLAN_LOCAL
and IFLA_VXLAN_GROUP.

The "Group" is renamed to "Remote" which is a multicast address.`

```
Description=vxlan-test
Name=vxlan1
Kind=vxlan

[VXLAN]
Id=33
Local=2001:db8:2f4:4bff:fa71:1a56
Remote=FF02:0:0:0:0:0:1:9
```

output
```
ip -d link show vxlan1
16: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1430 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fe:b4:97:03:f8:e5 brd ff:ff:ff:ff:ff:ff promiscuity 0
    vxlan id 33 group ff02::1:9 local 2001:db8:02f4:4bff:fa71:1a56 dev enp0s3 srcport 0 0 dstport 8472 ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

```

man/systemd.netdev.xml
src/network/netdev/netdev-gperf.gperf
src/network/netdev/vxlan.c
src/network/netdev/vxlan.h

index ef6a37f..39e6948 100644 (file)
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><varname>Group=</varname></term>
+        <term><varname>Remote=</varname></term>
         <listitem>
-          <para>An assigned multicast group IP address.</para>
+          <para>Configures destination multicast group IP address.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><varname>Local=</varname></term>
+        <listitem>
+          <para>Configures local IP address.</para>
+        </listitem>
+      </varlistentry>
+        <varlistentry>
         <term><varname>TOS=</varname></term>
         <listitem>
           <para>The Type Of Service byte value for a vxlan interface.</para>
index e74ae9e..e19fa98 100644 (file)
@@ -26,94 +26,96 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Match.Host,                  config_parse_net_condition,         CONDITION_HOST,                offsetof(NetDev, match_host)
-Match.Virtualization,        config_parse_net_condition,         CONDITION_VIRTUALIZATION,      offsetof(NetDev, match_virt)
-Match.KernelCommandLine,     config_parse_net_condition,         CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
-Match.Architecture,          config_parse_net_condition,         CONDITION_ARCHITECTURE,        offsetof(NetDev, match_arch)
-NetDev.Description,          config_parse_string,                0,                             offsetof(NetDev, description)
-NetDev.Name,                 config_parse_ifname,                0,                             offsetof(NetDev, ifname)
-NetDev.Kind,                 config_parse_netdev_kind,           0,                             offsetof(NetDev, kind)
-NetDev.MTUBytes,             config_parse_iec_size,              0,                             offsetof(NetDev, mtu)
-NetDev.MACAddress,           config_parse_hwaddr,                0,                             offsetof(NetDev, mac)
-VLAN.Id,                     config_parse_vlanid,                0,                             offsetof(VLan, id)
-MACVLAN.Mode,                config_parse_macvlan_mode,          0,                             offsetof(MacVlan, mode)
-MACVTAP.Mode,                config_parse_macvlan_mode,          0,                             offsetof(MacVlan, mode)
-IPVLAN.Mode,                 config_parse_ipvlan_mode,           0,                             offsetof(IPVlan, mode)
-Tunnel.Local,                config_parse_tunnel_address,        0,                             offsetof(Tunnel, local)
-Tunnel.Remote,               config_parse_tunnel_address,        0,                             offsetof(Tunnel, remote)
-Tunnel.TOS,                  config_parse_unsigned,              0,                             offsetof(Tunnel, tos)
-Tunnel.TTL,                  config_parse_unsigned,              0,                             offsetof(Tunnel, ttl)
-Tunnel.Key,                  config_parse_tunnel_key,            0,                             offsetof(Tunnel, key)
-Tunnel.InputKey,             config_parse_tunnel_key,            0,                             offsetof(Tunnel, ikey)
-Tunnel.OutputKey,            config_parse_tunnel_key,            0,                             offsetof(Tunnel, okey)
-Tunnel.DiscoverPathMTU,      config_parse_bool,                  0,                             offsetof(Tunnel, pmtudisc)
-Tunnel.Mode,                 config_parse_ip6tnl_mode,           0,                             offsetof(Tunnel, ip6tnl_mode)
-Tunnel.IPv6FlowLabel,        config_parse_ipv6_flowlabel,        0,                             offsetof(Tunnel, ipv6_flowlabel)
-Tunnel.CopyDSCP,             config_parse_bool,                  0,                             offsetof(Tunnel, copy_dscp)
-Tunnel.EncapsulationLimit,   config_parse_encap_limit,           0,                             offsetof(Tunnel, encap_limit)
-Peer.Name,                   config_parse_ifname,                0,                             offsetof(Veth, ifname_peer)
-Peer.MACAddress,             config_parse_hwaddr,                0,                             offsetof(Veth, mac_peer)
-VXLAN.Id,                    config_parse_uint64,                0,                             offsetof(VxLan, id)
-VXLAN.Group,                 config_parse_vxlan_group_address,   0,                             offsetof(VxLan, group)
-VXLAN.TOS,                   config_parse_unsigned,              0,                             offsetof(VxLan, tos)
-VXLAN.TTL,                   config_parse_unsigned,              0,                             offsetof(VxLan, ttl)
-VXLAN.MacLearning,           config_parse_bool,                  0,                             offsetof(VxLan, learning)
-VXLAN.ARPProxy,              config_parse_bool,                  0,                             offsetof(VxLan, arp_proxy)
-VXLAN.ReduceARPProxy,        config_parse_bool,                  0,                             offsetof(VxLan, arp_proxy)
-VXLAN.L2MissNotification,    config_parse_bool,                  0,                             offsetof(VxLan, l2miss)
-VXLAN.L3MissNotification,    config_parse_bool,                  0,                             offsetof(VxLan, l3miss)
-VXLAN.RouteShortCircuit,     config_parse_bool,                  0,                             offsetof(VxLan, route_short_circuit)
-VXLAN.UDPCheckSum,           config_parse_bool,                  0,                             offsetof(VxLan, udpcsum)
-VXLAN.UDPChecksum,           config_parse_bool,                  0,                             offsetof(VxLan, udpcsum)
-VXLAN.UDP6ZeroCheckSumRx,    config_parse_bool,                  0,                             offsetof(VxLan, udp6zerocsumrx)
-VXLAN.UDP6ZeroChecksumRx,    config_parse_bool,                  0,                             offsetof(VxLan, udp6zerocsumrx)
-VXLAN.UDP6ZeroCheckSumTx,    config_parse_bool,                  0,                             offsetof(VxLan, udp6zerocsumtx)
-VXLAN.UDP6ZeroChecksumTx,    config_parse_bool,                  0,                             offsetof(VxLan, udp6zerocsumtx)
-VXLAN.RemoteChecksumTx,      config_parse_bool,                  0,                             offsetof(VxLan, remote_csum_tx)
-VXLAN.RemoteChecksumRx,      config_parse_bool,                  0,                             offsetof(VxLan, remote_csum_rx)
-VXLAN.FDBAgeingSec,          config_parse_sec,                   0,                             offsetof(VxLan, fdb_ageing)
-VXLAN.GroupPolicyExtension,  config_parse_bool,                  0,                             offsetof(VxLan, group_policy)
-VXLAN.MaximumFDBEntries,     config_parse_unsigned,              0,                             offsetof(VxLan, max_fdb)
-VXLAN.PortRange,             config_parse_port_range,            0,                             0
-VXLAN.DestinationPort,       config_parse_destination_port,      0,                             offsetof(VxLan, dest_port)
-Tun.OneQueue,                config_parse_bool,                  0,                             offsetof(TunTap, one_queue)
-Tun.MultiQueue,              config_parse_bool,                  0,                             offsetof(TunTap, multi_queue)
-Tun.PacketInfo,              config_parse_bool,                  0,                             offsetof(TunTap, packet_info)
-Tun.User,                    config_parse_string,                0,                             offsetof(TunTap, user_name)
-Tun.Group,                   config_parse_string,                0,                             offsetof(TunTap, group_name)
-Tap.OneQueue,                config_parse_bool,                  0,                             offsetof(TunTap, one_queue)
-Tap.MultiQueue,              config_parse_bool,                  0,                             offsetof(TunTap, multi_queue)
-Tap.PacketInfo,              config_parse_bool,                  0,                             offsetof(TunTap, packet_info)
-Tap.VNetHeader,              config_parse_bool,                  0,                             offsetof(TunTap, vnet_hdr)
-Tap.User,                    config_parse_string,                0,                             offsetof(TunTap, user_name)
-Tap.Group,                   config_parse_string,                0,                             offsetof(TunTap, group_name)
-Bond.Mode,                   config_parse_bond_mode,             0,                             offsetof(Bond, mode)
-Bond.TransmitHashPolicy,     config_parse_bond_xmit_hash_policy, 0,                             offsetof(Bond, xmit_hash_policy)
-Bond.LACPTransmitRate,       config_parse_bond_lacp_rate,        0,                             offsetof(Bond, lacp_rate)
-Bond.AdSelect,               config_parse_bond_ad_select,        0,                             offsetof(Bond, ad_select)
-Bond.FailOverMACPolicy,      config_parse_bond_fail_over_mac,    0,                             offsetof(Bond, fail_over_mac)
-Bond.ARPIPTargets,           config_parse_arp_ip_target_address, 0,                             0
-Bond.ARPValidate,            config_parse_bond_arp_validate,     0,                             offsetof(Bond, arp_validate)
-Bond.ARPAllTargets,          config_parse_bond_arp_all_targets,  0,                             offsetof(Bond, arp_all_targets)
-Bond.PrimaryReselectPolicy,  config_parse_bond_primary_reselect, 0,                             offsetof(Bond, primary_reselect)
-Bond.ResendIGMP,             config_parse_unsigned,              0,                             offsetof(Bond, resend_igmp)
-Bond.PacketsPerSlave,        config_parse_unsigned,              0,                             offsetof(Bond, packets_per_slave)
-Bond.GratuitousARP,          config_parse_unsigned,              0,                             offsetof(Bond, num_grat_arp)
-Bond.AllSlavesActive,        config_parse_unsigned,              0,                             offsetof(Bond, all_slaves_active)
-Bond.MinLinks,               config_parse_unsigned,              0,                             offsetof(Bond, min_links)
-Bond.MIIMonitorSec,          config_parse_sec,                   0,                             offsetof(Bond, miimon)
-Bond.UpDelaySec,             config_parse_sec,                   0,                             offsetof(Bond, updelay)
-Bond.DownDelaySec,           config_parse_sec,                   0,                             offsetof(Bond, downdelay)
-Bond.ARPIntervalSec,         config_parse_sec,                   0,                             offsetof(Bond, arp_interval)
-Bond.LearnPacketIntervalSec, config_parse_sec,                   0,                             offsetof(Bond, lp_interval)
-Bridge.HelloTimeSec,         config_parse_sec,                   0,                             offsetof(Bridge, hello_time)
-Bridge.MaxAgeSec,            config_parse_sec,                   0,                             offsetof(Bridge, max_age)
-Bridge.AgeingTimeSec,        config_parse_sec,                   0,                             offsetof(Bridge, ageing_time)
-Bridge.ForwardDelaySec,      config_parse_sec,                   0,                             offsetof(Bridge, forward_delay)
-Bridge.Priority,             config_parse_uint16,                0,                             offsetof(Bridge, priority)
-Bridge.DefaultPVID,          config_parse_vlanid,                0,                             offsetof(Bridge, default_pvid)
-Bridge.MulticastQuerier,     config_parse_tristate,              0,                             offsetof(Bridge, mcast_querier)
-Bridge.MulticastSnooping,    config_parse_tristate,              0,                             offsetof(Bridge, mcast_snooping)
-Bridge.VLANFiltering,        config_parse_tristate,              0,                             offsetof(Bridge, vlan_filtering)
-Bridge.STP,                  config_parse_tristate,              0,                             offsetof(Bridge, stp)
-VRF.TableId,                 config_parse_uint32,                0,                             offsetof(Vrf, table_id)
+Match.Host,                  config_parse_net_condition,           CONDITION_HOST,                offsetof(NetDev, match_host)
+Match.Virtualization,        config_parse_net_condition,           CONDITION_VIRTUALIZATION,      offsetof(NetDev, match_virt)
+Match.KernelCommandLine,     config_parse_net_condition,           CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
+Match.Architecture,          config_parse_net_condition,           CONDITION_ARCHITECTURE,        offsetof(NetDev, match_arch)
+NetDev.Description,          config_parse_string,                  0,                             offsetof(NetDev, description)
+NetDev.Name,                 config_parse_ifname,                  0,                             offsetof(NetDev, ifname)
+NetDev.Kind,                 config_parse_netdev_kind,             0,                             offsetof(NetDev, kind)
+NetDev.MTUBytes,             config_parse_iec_size,                0,                             offsetof(NetDev, mtu)
+NetDev.MACAddress,           config_parse_hwaddr,                  0,                             offsetof(NetDev, mac)
+VLAN.Id,                     config_parse_vlanid,                  0,                             offsetof(VLan, id)
+MACVLAN.Mode,                config_parse_macvlan_mode,            0,                             offsetof(MacVlan, mode)
+MACVTAP.Mode,                config_parse_macvlan_mode,            0,                             offsetof(MacVlan, mode)
+IPVLAN.Mode,                 config_parse_ipvlan_mode,             0,                             offsetof(IPVlan, mode)
+Tunnel.Local,                config_parse_tunnel_address,          0,                             offsetof(Tunnel, local)
+Tunnel.Remote,               config_parse_tunnel_address,          0,                             offsetof(Tunnel, remote)
+Tunnel.TOS,                  config_parse_unsigned,                0,                             offsetof(Tunnel, tos)
+Tunnel.TTL,                  config_parse_unsigned,                0,                             offsetof(Tunnel, ttl)
+Tunnel.Key,                  config_parse_tunnel_key,              0,                             offsetof(Tunnel, key)
+Tunnel.InputKey,             config_parse_tunnel_key,              0,                             offsetof(Tunnel, ikey)
+Tunnel.OutputKey,            config_parse_tunnel_key,              0,                             offsetof(Tunnel, okey)
+Tunnel.DiscoverPathMTU,      config_parse_bool,                    0,                             offsetof(Tunnel, pmtudisc)
+Tunnel.Mode,                 config_parse_ip6tnl_mode,             0,                             offsetof(Tunnel, ip6tnl_mode)
+Tunnel.IPv6FlowLabel,        config_parse_ipv6_flowlabel,          0,                             offsetof(Tunnel, ipv6_flowlabel)
+Tunnel.CopyDSCP,             config_parse_bool,                    0,                             offsetof(Tunnel, copy_dscp)
+Tunnel.EncapsulationLimit,   config_parse_encap_limit,             0,                             offsetof(Tunnel, encap_limit)
+Peer.Name,                   config_parse_ifname,                  0,                             offsetof(Veth, ifname_peer)
+Peer.MACAddress,             config_parse_hwaddr,                  0,                             offsetof(Veth, mac_peer)
+VXLAN.Id,                    config_parse_uint64,                  0,                             offsetof(VxLan, id)
+VXLAN.Group,                 config_parse_vxlan_address,           0,                             offsetof(VxLan, remote)
+VXLAN.Local,                 config_parse_vxlan_address,           0,                             offsetof(VxLan, local)
+VXLAN.Remote,                config_parse_vxlan_address,           0,                             offsetof(VxLan, remote)
+VXLAN.TOS,                   config_parse_unsigned,                0,                             offsetof(VxLan, tos)
+VXLAN.TTL,                   config_parse_unsigned,                0,                             offsetof(VxLan, ttl)
+VXLAN.MacLearning,           config_parse_bool,                    0,                             offsetof(VxLan, learning)
+VXLAN.ARPProxy,              config_parse_bool,                    0,                             offsetof(VxLan, arp_proxy)
+VXLAN.ReduceARPProxy,        config_parse_bool,                    0,                             offsetof(VxLan, arp_proxy)
+VXLAN.L2MissNotification,    config_parse_bool,                    0,                             offsetof(VxLan, l2miss)
+VXLAN.L3MissNotification,    config_parse_bool,                    0,                             offsetof(VxLan, l3miss)
+VXLAN.RouteShortCircuit,     config_parse_bool,                    0,                             offsetof(VxLan, route_short_circuit)
+VXLAN.UDPCheckSum,           config_parse_bool,                    0,                             offsetof(VxLan, udpcsum)
+VXLAN.UDPChecksum,           config_parse_bool,                    0,                             offsetof(VxLan, udpcsum)
+VXLAN.UDP6ZeroCheckSumRx,    config_parse_bool,                    0,                             offsetof(VxLan, udp6zerocsumrx)
+VXLAN.UDP6ZeroChecksumRx,    config_parse_bool,                    0,                             offsetof(VxLan, udp6zerocsumrx)
+VXLAN.UDP6ZeroCheckSumTx,    config_parse_bool,                    0,                             offsetof(VxLan, udp6zerocsumtx)
+VXLAN.UDP6ZeroChecksumTx,    config_parse_bool,                    0,                             offsetof(VxLan, udp6zerocsumtx)
+VXLAN.RemoteChecksumTx,      config_parse_bool,                    0,                             offsetof(VxLan, remote_csum_tx)
+VXLAN.RemoteChecksumRx,      config_parse_bool,                    0,                             offsetof(VxLan, remote_csum_rx)
+VXLAN.FDBAgeingSec,          config_parse_sec,                     0,                             offsetof(VxLan, fdb_ageing)
+VXLAN.GroupPolicyExtension,  config_parse_bool,                    0,                             offsetof(VxLan, group_policy)
+VXLAN.MaximumFDBEntries,     config_parse_unsigned,                0,                             offsetof(VxLan, max_fdb)
+VXLAN.PortRange,             config_parse_port_range,              0,                             0
+VXLAN.DestinationPort,       config_parse_destination_port,        0,                             offsetof(VxLan, dest_port)
+Tun.OneQueue,                config_parse_bool,                    0,                             offsetof(TunTap, one_queue)
+Tun.MultiQueue,              config_parse_bool,                    0,                             offsetof(TunTap, multi_queue)
+Tun.PacketInfo,              config_parse_bool,                    0,                             offsetof(TunTap, packet_info)
+Tun.User,                    config_parse_string,                  0,                             offsetof(TunTap, user_name)
+Tun.Group,                   config_parse_string,                  0,                             offsetof(TunTap, group_name)
+Tap.OneQueue,                config_parse_bool,                    0,                             offsetof(TunTap, one_queue)
+Tap.MultiQueue,              config_parse_bool,                    0,                             offsetof(TunTap, multi_queue)
+Tap.PacketInfo,              config_parse_bool,                    0,                             offsetof(TunTap, packet_info)
+Tap.VNetHeader,              config_parse_bool,                    0,                             offsetof(TunTap, vnet_hdr)
+Tap.User,                    config_parse_string,                  0,                             offsetof(TunTap, user_name)
+Tap.Group,                   config_parse_string,                  0,                             offsetof(TunTap, group_name)
+Bond.Mode,                   config_parse_bond_mode,               0,                             offsetof(Bond, mode)
+Bond.TransmitHashPolicy,     config_parse_bond_xmit_hash_policy,   0,                             offsetof(Bond, xmit_hash_policy)
+Bond.LACPTransmitRate,       config_parse_bond_lacp_rate,          0,                             offsetof(Bond, lacp_rate)
+Bond.AdSelect,               config_parse_bond_ad_select,          0,                             offsetof(Bond, ad_select)
+Bond.FailOverMACPolicy,      config_parse_bond_fail_over_mac,      0,                             offsetof(Bond, fail_over_mac)
+Bond.ARPIPTargets,           config_parse_arp_ip_target_address,   0,                             0
+Bond.ARPValidate,            config_parse_bond_arp_validate,       0,                             offsetof(Bond, arp_validate)
+Bond.ARPAllTargets,          config_parse_bond_arp_all_targets,    0,                             offsetof(Bond, arp_all_targets)
+Bond.PrimaryReselectPolicy,  config_parse_bond_primary_reselect,   0,                             offsetof(Bond, primary_reselect)
+Bond.ResendIGMP,             config_parse_unsigned,                0,                             offsetof(Bond, resend_igmp)
+Bond.PacketsPerSlave,        config_parse_unsigned,                0,                             offsetof(Bond, packets_per_slave)
+Bond.GratuitousARP,          config_parse_unsigned,                0,                             offsetof(Bond, num_grat_arp)
+Bond.AllSlavesActive,        config_parse_unsigned,                0,                             offsetof(Bond, all_slaves_active)
+Bond.MinLinks,               config_parse_unsigned,                0,                             offsetof(Bond, min_links)
+Bond.MIIMonitorSec,          config_parse_sec,                     0,                             offsetof(Bond, miimon)
+Bond.UpDelaySec,             config_parse_sec,                     0,                             offsetof(Bond, updelay)
+Bond.DownDelaySec,           config_parse_sec,                     0,                             offsetof(Bond, downdelay)
+Bond.ARPIntervalSec,         config_parse_sec,                     0,                             offsetof(Bond, arp_interval)
+Bond.LearnPacketIntervalSec, config_parse_sec,                     0,                             offsetof(Bond, lp_interval)
+Bridge.HelloTimeSec,         config_parse_sec,                     0,                             offsetof(Bridge, hello_time)
+Bridge.MaxAgeSec,            config_parse_sec,                     0,                             offsetof(Bridge, max_age)
+Bridge.AgeingTimeSec,        config_parse_sec,                     0,                             offsetof(Bridge, ageing_time)
+Bridge.ForwardDelaySec,      config_parse_sec,                     0,                             offsetof(Bridge, forward_delay)
+Bridge.Priority,             config_parse_uint16,                  0,                             offsetof(Bridge, priority)
+Bridge.DefaultPVID,          config_parse_vlanid,                  0,                             offsetof(Bridge, default_pvid)
+Bridge.MulticastQuerier,     config_parse_tristate,                0,                             offsetof(Bridge, mcast_querier)
+Bridge.MulticastSnooping,    config_parse_tristate,                0,                             offsetof(Bridge, mcast_snooping)
+Bridge.VLANFiltering,        config_parse_tristate,                0,                             offsetof(Bridge, vlan_filtering)
+Bridge.STP,                  config_parse_tristate,                0,                             offsetof(Bridge, stp)
+VRF.TableId,                 config_parse_uint32,                  0,                             offsetof(Vrf, table_id)
index 231f5cb..b677b00 100644 (file)
@@ -24,6 +24,8 @@
 #include "conf-parser.h"
 #include "alloc-util.h"
 #include "extract-word.h"
+#include "string-util.h"
+#include "strv.h"
 #include "parse-util.h"
 #include "missing.h"
 
@@ -48,9 +50,29 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
         }
 
-        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
-        if (r < 0)
-                return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
+        if (!in_addr_is_null(v->remote_family, &v->remote)) {
+
+                if (v->remote_family == AF_INET)
+                        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->remote.in);
+                else
+                        r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->remote.in6);
+
+                if (r < 0)
+                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
+
+        }
+
+        if (!in_addr_is_null(v->local_family, &v->local)) {
+
+                if (v->local_family == AF_INET)
+                        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_LOCAL, &v->local.in);
+                else
+                        r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_LOCAL6, &v->local.in6);
+
+                if (r < 0)
+                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LOCAL attribute: %m");
+
+        }
 
         r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
         if (r < 0)
@@ -144,16 +166,16 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
         return r;
 }
 
-int config_parse_vxlan_group_address(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) {
+int config_parse_vxlan_address(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) {
         VxLan *v = userdata;
         union in_addr_union *addr = data, buffer;
         int r, f;
@@ -165,16 +187,28 @@ int config_parse_vxlan_group_address(const char *unit,
 
         r = in_addr_from_string_auto(rvalue, &f, &buffer);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "vxlan '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue);
                 return 0;
         }
 
-        if (v->family != AF_UNSPEC && v->family != f) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
-                return 0;
+        r = in_addr_is_multicast(f, &buffer);
+
+        if (STR_IN_SET(lvalue, "Group", "Remote")) {
+                if (r <= 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue);
+                        return 0;
+                }
+
+                v->remote_family = f;
+        } else {
+                if (r > 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan %s can not be multicast address, ignoring assignment: %s", lvalue, rvalue);
+                        return 0;
+                }
+
+                v->local_family = f;
         }
 
-        v->family = f;
         *addr = buffer;
 
         return 0;
index 6c3081d..dca58e7 100644 (file)
@@ -31,8 +31,11 @@ struct VxLan {
 
         uint64_t id;
 
-        int family;
-        union in_addr_union group;
+        int remote_family;
+        int local_family;
+
+        union in_addr_union remote;
+        union in_addr_union local;
 
         unsigned tos;
         unsigned ttl;
@@ -60,16 +63,16 @@ struct VxLan {
 DEFINE_NETDEV_CAST(VXLAN, VxLan);
 extern const NetDevVTable vxlan_vtable;
 
-int config_parse_vxlan_group_address(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);
+int config_parse_vxlan_address(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);
 int config_parse_port_range(const char *unit,
                             const char *filename,
                             unsigned line,