diff options
Diffstat (limited to 'src/nm-netlink-compat.c')
| -rw-r--r-- | src/nm-netlink-compat.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c index e91a1ff2..974121ad 100644 --- a/src/nm-netlink-compat.c +++ b/src/nm-netlink-compat.c @@ -20,7 +20,13 @@ #include <config.h> #include <glib.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <linux/if_vlan.h> +#include <linux/sockios.h> +#include "nm-logging.h" #include "nm-netlink-compat.h" #ifndef HAVE_LIBNL1 @@ -102,4 +108,135 @@ nl_compat_error (int err) return -err; } + +int +rtnl_link_vlan_get_id (struct rtnl_link *l) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + strcpy (if_request.device1, if_name); + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + if_request.cmd = GET_VLAN_VID_CMD; + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't get vlan id for %s.", if_name); + goto err_out; + } + + close(fd); + return if_request.u.VID; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_flags (struct rtnl_link *l, unsigned int flags) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_FLAG_CMD; + if_request.u.flag = flags; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set flag in device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_ingress_map (struct rtnl_link *l, int from, uint32_t to) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD; + if_request.u.skb_priority = from; + if_request.vlan_qos = to; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set ingress map on device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_egress_map (struct rtnl_link *l, int from, uint32_t to) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD; + if_request.u.skb_priority = from; + if_request.vlan_qos = to; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set egress map on device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} #endif |