Skip to content

Commit

Permalink
Changes to support Ubuntu 16.04 v4.15 kernel.
Browse files Browse the repository at this point in the history
DPDK: Ubuntu 16.04 compilation fix

Partial-Bug: 1638643

Changes to make vrouter code compile against linux kernel v4.15. Timer_list
structure has changed in 4.15 releases. Also some changes introduced to
vr_host_interface.c, removing NETIF_F_UFO reference for v4.15.

closes-bug: #1765229

Fix vrouter build for kernels from 4.11 to 4.13

- linux/vhost_dev.c:
  Rename netdev destructor to priv_destructor due to API change.
  New signature of rtnl_link_ops.validate due to API change.
- linux/vr_mem.c
  Remove vma from mem_fault function since VMA pointer now accessable
  via VMF structure.

Partial-Bug: #1633387
(cherry picked from commit 60c9031)

Modify generic netlink family registration for kernel 4.10 support
Closes-bug: #1696745

Fix netlink family registration for kernel 4.10

When we call genl_register_family with "ops" field provided,
we need to provide "n_ops" field as well.

Closes-bug: #1696745

Register information about multicast group

Pass to vrouter module information about multicast group. Withouth that
user space client (vif) was unable to join vrouter netlink broadcast group
when kernel 4.10 or higher was used.

Closes-Bug: #1771999

Change-Id: I7d01633fca50a3c76ce1ea9d9233623e4a2abd45
Closes Jira Bug:JCB-218796
  • Loading branch information
kirankn80 authored and Saurabh committed Jan 23, 2019
1 parent 5954d3a commit 436c78d
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 19 deletions.
2 changes: 1 addition & 1 deletion include/vr_dpdk.h
Expand Up @@ -658,7 +658,7 @@ int vr_dpdk_ulog(uint32_t level, uint32_t logtype, uint32_t *last_hash,
void dpdk_adjust_tcp_mss(struct tcphdr *tcph, unsigned short overlay_len,
unsigned char iph_len);
/* Creates a copy of the given packet mbuf */
inline struct rte_mbuf *
struct rte_mbuf *
vr_dpdk_pktmbuf_copy(struct rte_mbuf *md, struct rte_mempool *mp);

/*
Expand Down
5 changes: 5 additions & 0 deletions include/vrouter.h
Expand Up @@ -135,7 +135,12 @@ struct vr_ip;
struct vr_timer {
void (*vt_timer)(void *);
void *vt_vr_arg;
#if (defined(__linux__) && defined(__KERNEL__))
struct timer_list timer;
#else
void *vt_os_arg;
#endif
unsigned int vt_stop_timer;
unsigned int vt_msecs;
};

Expand Down
13 changes: 12 additions & 1 deletion linux/vhost_dev.c
Expand Up @@ -463,7 +463,12 @@ vhost_setup(struct net_device *dev)

dev->needed_headroom = sizeof(struct vr_eth) + sizeof(struct agent_hdr);
dev->netdev_ops = &vhost_dev_ops;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,9))
dev->priv_destructor = vhost_dev_destructor;
dev->needs_free_netdev = true;
#else
dev->destructor = vhost_dev_destructor;
#endif /*KERNEL_4.11*/
#ifdef CONFIG_XEN
dev->ethtool_ops = &vhost_ethtool_ops;
dev->features |= NETIF_F_GRO;
Expand Down Expand Up @@ -514,8 +519,15 @@ vhost_dellink(struct net_device *dev, struct list_head *head)
return;
}


#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0))
static int
vhost_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
#else
static int
vhost_validate(struct nlattr *tb[], struct nlattr *data[])
#endif /*KERNEL_4.13*/
{
if (vhost_num_interfaces >= VHOST_MAX_INTERFACES)
return -ENOMEM;
Expand All @@ -531,7 +543,6 @@ static struct rtnl_link_ops vhost_link_ops = {
.dellink = vhost_dellink,
};


static void
vhost_netlink_exit(void)
{
Expand Down
21 changes: 16 additions & 5 deletions linux/vr_genetlink.c
Expand Up @@ -19,9 +19,10 @@
#include "sandesh.h"
#include "vr_response.h"

#if (defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) || \
(defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
#define GENL_ID_GENERATE 0
#endif
#endif /* Linux 4.10.0 */
static int netlink_trans_request(struct sk_buff *, struct genl_info *);

static struct genl_ops vrouter_genl_ops[] = {
Expand All @@ -32,16 +33,25 @@ static struct genl_ops vrouter_genl_ops[] = {
},
};

/* This becomes the group id 0x4 since group id allocation starts at */
/* 0x4 and it is the only group for this family */
struct genl_multicast_group vrouter_genl_groups[] = {
{ .name = "VRouterGroup" },
};

struct genl_family vrouter_genl_family = {
.id = GENL_ID_GENERATE,
.name = "vrouter",
.version = 1,
.maxattr = NL_ATTR_MAX - 1,
.netnsok = true,
#if (defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) || \
(defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
.ops = vrouter_genl_ops,
.n_ops = ARRAY_SIZE(vrouter_genl_ops),
#endif
.mcgrps = vrouter_genl_groups,
.n_mcgrps = ARRAY_SIZE(vrouter_genl_groups),
#endif /* Linux 4.10.0 */
};

#define NETLINK_RESPONSE_HEADER_LEN (NLMSG_HDRLEN + GENL_HDRLEN + \
Expand Down Expand Up @@ -187,7 +197,8 @@ vr_genetlink_init(void)
(!(defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7))))
return genl_register_family_with_ops(&vrouter_genl_family, vrouter_genl_ops,
ARRAY_SIZE(vrouter_genl_ops));
#elif (defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) || \
(defined(RHEL_MAJOR) && (RHEL_MAJOR >= 7) && (RHEL_MINOR >= 5))
return genl_register_family(&vrouter_genl_family);
#else
return genl_register_family_with_ops(&vrouter_genl_family,
Expand Down
8 changes: 6 additions & 2 deletions linux/vr_host_interface.c
Expand Up @@ -247,7 +247,9 @@ linux_inet_fragment(struct vr_interface *vif, struct sk_buff *skb,
netdev_features_t features;

features = netif_skb_features(skb);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0))
features &= (~(NETIF_F_ALL_TSO | NETIF_F_GSO));
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
features &= (~(NETIF_F_ALL_TSO | NETIF_F_UFO | NETIF_F_GSO));
#else
features &= ~(NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO);
Expand Down Expand Up @@ -493,7 +495,9 @@ linux_gso_xmit(struct vr_interface *vif, struct sk_buff *skb,
struct net_device *ndev = (struct net_device *)vif->vif_os;

features = netif_skb_features(skb);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0))
features &= (~(NETIF_F_ALL_TSO | NETIF_F_GSO));
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
features &= (~(NETIF_F_ALL_TSO | NETIF_F_UFO | NETIF_F_GSO));
#else
features &= (~(NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO));
Expand Down
9 changes: 9 additions & 0 deletions linux/vr_mem.c
Expand Up @@ -5,6 +5,7 @@
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#include <linux/init.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
Expand All @@ -22,10 +23,18 @@ short vr_flow_major = -1;
static dev_t mem_dev;
struct cdev *mem_cdev;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0))
static int
mem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct vrouter *router = (struct vrouter *)vma->vm_private_data;
#else
static int
mem_fault(struct vm_fault *vmf)
{
struct vrouter *router =
(struct vrouter *)vmf->vma->vm_private_data;
#endif /*KERNEL_4.11*/
struct page *page;
pgoff_t offset;

Expand Down
44 changes: 34 additions & 10 deletions linux/vrouter_mod.c
Expand Up @@ -2046,11 +2046,22 @@ lh_network_header(struct vr_packet *pkt)
return NULL;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)
typedef unsigned long linux_timer_callback_param_t;
#else
typedef struct timer_list * linux_timer_callback_param_t;
#endif

static void
linux_timer(unsigned long arg)
linux_timer(linux_timer_callback_param_t arg)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)
struct vr_timer *vtimer = (struct vr_timer *)arg;
struct timer_list *timer = (struct timer_list *)vtimer->vt_os_arg;
struct timer_list *timer = &vtimer->timer;
#else
struct timer_list *timer = arg;
struct vr_timer *vtimer = from_timer(vtimer, timer, timer);
#endif

vtimer->vt_timer(vtimer->vt_vr_arg);
mod_timer(timer, get_jiffies_64() + msecs_to_jiffies(vtimer->vt_msecs));
Expand All @@ -2061,30 +2072,43 @@ linux_timer(unsigned long arg)
static void
lh_delete_timer(struct vr_timer *vtimer)
{
struct timer_list *timer = (struct timer_list *)vtimer->vt_os_arg;
struct timer_list *timer = &vtimer->timer;

if (timer) {
del_timer_sync(timer);
vr_free(vtimer->vt_os_arg, VR_TIMER_OBJECT);
vtimer->vt_os_arg = NULL;
}

return;
}

static int
lh_restart_timer(struct vr_timer *vtimer)
{
struct timer_list *timer = &vtimer->timer;
if (!timer || !vtimer->vt_msecs)
return -1;

vtimer->vt_stop_timer = 0;

mod_timer(timer, get_jiffies_64() + msecs_to_jiffies(vtimer->vt_msecs));

return 0;
}

static int
lh_create_timer(struct vr_timer *vtimer)
{
struct timer_list *timer;

timer = vr_zalloc(sizeof(*timer), VR_TIMER_OBJECT);
if (!timer)
return -ENOMEM;
timer = &vtimer->timer;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)
init_timer(timer);

vtimer->vt_os_arg = (void *)timer;
timer->data = (unsigned long)vtimer;
timer->function = linux_timer;
#else
/* timer_list api has changed in 4.15 */
timer_setup(timer, linux_timer, 0);
#endif
timer->expires = get_jiffies_64() + msecs_to_jiffies(vtimer->vt_msecs);
timer->expires = get_jiffies_64() + msecs_to_jiffies(vtimer->vt_msecs);
add_timer(timer);
Expand Down

0 comments on commit 436c78d

Please sign in to comment.