diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index e23f7d1f49e0..e9e0f75e0443 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -352,8 +352,10 @@ static int ovpn_nl_peer_modify(struct ovpn_peer *peer, struct genl_info *info, int ovpn_nl_peer_new_doit(struct sk_buff *skb, struct genl_info *info) { - struct nlattr *attrs[OVPN_A_PEER_MAX + 1]; + struct in_addr vpn_addr4 = { .s_addr = htonl(INADDR_ANY) }; + struct in6_addr vpn_addr6 = IN6ADDR_ANY_INIT; struct ovpn_priv *ovpn = info->user_ptr[0]; + struct nlattr *attrs[OVPN_A_PEER_MAX + 1]; struct ovpn_socket *ovpn_sock; struct socket *sock = NULL; struct ovpn_peer *peer; @@ -377,11 +379,20 @@ int ovpn_nl_peer_new_doit(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* in MP mode VPN IPs are required for selecting the right peer */ - if (ovpn->mode == OVPN_MODE_MP && !attrs[OVPN_A_PEER_VPN_IPV4] && - !attrs[OVPN_A_PEER_VPN_IPV6]) { - NL_SET_ERR_MSG_FMT_MOD(info->extack, - "VPN IP must be provided in MP mode"); - return -EINVAL; + if (ovpn->mode == OVPN_MODE_MP) { + if (attrs[OVPN_A_PEER_VPN_IPV4]) + vpn_addr4.s_addr = + nla_get_in_addr(attrs[OVPN_A_PEER_VPN_IPV4]); + if (attrs[OVPN_A_PEER_VPN_IPV6]) + vpn_addr6 = + nla_get_in6_addr(attrs[OVPN_A_PEER_VPN_IPV6]); + + if (vpn_addr4.s_addr == htonl(INADDR_ANY) && + ipv6_addr_any(&vpn_addr6)) { + NL_SET_ERR_MSG_FMT_MOD(info->extack, + "at least one VPN IP must be configured in MP mode"); + return -EINVAL; + } } peer_id = nla_get_u32(attrs[OVPN_A_PEER_ID]); @@ -531,6 +542,9 @@ int ovpn_nl_peer_set_doit(struct sk_buff *skb, struct genl_info *info) spin_lock_bh(&ovpn->lock); + vpn_addr4 = peer->vpn_addrs.ipv4; + vpn_addr6 = peer->vpn_addrs.ipv6; + /* reject peer with conflicting VPN address */ if (attrs[OVPN_A_PEER_VPN_IPV4]) { vpn_addr4.s_addr = nla_get_in_addr(attrs[OVPN_A_PEER_VPN_IPV4]); @@ -543,6 +557,16 @@ int ovpn_nl_peer_set_doit(struct sk_buff *skb, struct genl_info *info) goto addr_conflict; } + /* in MP mode VPN IPs are required for selecting the right peer */ + if (ovpn->mode == OVPN_MODE_MP && + vpn_addr4.s_addr == htonl(INADDR_ANY) && + ipv6_addr_any(&vpn_addr6)) { + NL_SET_ERR_MSG_FMT_MOD(info->extack, + "at least one VPN IP must be configured in MP mode"); + ret = -EINVAL; + goto unlock; + } + ret = ovpn_nl_peer_modify(peer, info, attrs); if (ret < 0) goto unlock;