blob: 9ffc93b226f14d4b3cd68e93d10b38d87465de40 [file] [log] [blame]
/*
***************************************************************************
* Copyright (c) 2015-2016,2018-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
***************************************************************************
*/
#include <linux/version.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <net/genetlink.h>
#include <nss_api_if.h>
#include <nss_nl_if.h>
#include "nss_nlcmn_if.h"
#include "nss_nl.h"
#include "nss_nlgre_redir_if.h"
#include "nss_nlgre_redir_cmn.h"
#include "nss_nlgre_redir.h"
/*
* nss_nlgre_redir_destroy_tun()
* Destroys the gre_redir tunnel
*/
int nss_nlgre_redir_destroy_tun(struct net_device *dev)
{
int ret;
if (!dev) {
nss_nl_error("Dev is NULL\n");
return -EINVAL;
}
ret = nss_nlgre_redir_cmn_destroy_tun(dev);
if (ret < 0) {
nss_nl_error("Could not destroy the tunnel\n");
return -EINVAL;
}
nss_nl_info("Successfully destroyed the tunnel\n");
return 0;
}
/*
* nss_nlgre_redir_create_tun()
* Creates a gre_redir tunnel
*/
int nss_nlgre_redir_create_tun(struct nss_nlgre_redir_create_tun *create_params)
{
struct net_device *dev;
if (!create_params) {
nss_nl_error("create_params is NULL\n");
return -EINVAL;
}
dev = nss_nlgre_redir_cmn_create_tun(create_params->sip, create_params->dip, create_params->iptype);
if (!dev) {
nss_nl_error("Could not create tunnel\n");
return -EINVAL;
}
nss_nl_info("Successfully created the tunnel = %s\n", dev->name);
return 0;
}
/*
* nss_nlgre_redir_map_interface()
* Maps the nss interface to the tunnel ID
*/
int nss_nlgre_redir_map_interface(struct nss_nlgre_redir_map *map_params)
{
struct nss_ctx_instance *nss_ctx;
uint32_t nexthop_nssif, vap_nss_if;
uint8_t tun_type;
int ret;
if (!map_params) {
nss_nl_error("map params is NULL\n");
return -EINVAL;
}
nss_ctx = nss_gre_redir_get_context();
vap_nss_if = nss_nlgre_redir_cmn_get_dev_ifnum(map_params->vap_nss_if);
/*
* Get tunnel type from tun_type string
*/
tun_type = nss_nlgre_redir_cmn_get_tun_type(map_params->tun_type);
switch(tun_type) {
case NSS_NLGRE_REDIR_TUN_TYPE_DTUN:
case NSS_NLGRE_REDIR_TUN_TYPE_TUN:
nexthop_nssif = vap_nss_if;
break;
case NSS_NLGRE_REDIR_TUN_TYPE_SPLIT:
nexthop_nssif = NSS_ETH_RX_INTERFACE;
break;
default:
nss_nl_error("%px: not a valid tunnel_type\n", nss_ctx);
return -1;
}
/*
* Map the nss interface
*/
ret = nss_nlgre_redir_cmn_map_interface(nexthop_nssif, 0, map_params);
if (ret == -1) {
nss_nl_error("%px: Unable to map nss interface\n", nss_ctx);
return -1;
}
nss_nl_info("Successfully mapped the nss interface to tunnel ID\n");
return 0;
}
/*
* nss_nlgre_redir_set_next_hop()
* Sets the next hop of vap as wifi_offld_inner interface of gre_redir node
*/
int nss_nlgre_redir_set_next_hop(struct nss_nlgre_redir_set_next *set_next_params)
{
enum nss_nlgre_redir_cmn_mode_type mode;
struct nss_ctx_instance *nss_ctx;
struct net_device *next_dev;
uint32_t nexthop_ifnum;
int ret;
if (!set_next_params) {
nss_nl_error("set next params is NULL\n");
return -EINVAL;
}
nss_ctx = nss_gre_redir_get_context();
next_dev = dev_get_by_name(&init_net, set_next_params->next_dev_name);
if (!next_dev) {
nss_nl_error("%px: Unable to get the reference to dev %s\n", nss_ctx, set_next_params->next_dev_name);
return -1;
}
dev_put(next_dev);
mode = nss_nlgre_redir_cmn_mode_str_to_enum(set_next_params->mode);
switch(mode) {
case NSS_NLGRE_REDIR_CMN_MODE_TYPE_WIFI:
/*
* Gets the wifi_offl_inner_ifnum interface number of gretun[index]
*/
nexthop_ifnum = nss_nlgre_redir_cmn_get_tun_ifnum(NSS_NLGRE_REDIR_CMN_MODE_TYPE_WIFI, next_dev);
break;
case NSS_NLGRE_REDIR_CMN_MODE_TYPE_SPLIT:
nexthop_ifnum = NSS_ETH_RX_INTERFACE;
break;
default:
nss_nl_error("%px: Unknown set next mode\n", nss_ctx);
return -1;
}
ret = nss_nlgre_redir_cmn_set_next_hop(nexthop_ifnum, set_next_params);
if (ret == -1) {
nss_nl_error("%px: Unable to set the next hop\n", nss_ctx);
return -1;
}
nss_nl_info("Successfully set the next hop\n");
return 0;
}