Thank u for reviewing my codes.:)
δΊ 2012-1-20 3:06, Sharad Mishra ει:
libvirt-cim-bounces(a)redhat.com wrote on 01/18/2012 01:42:00 AM:
> Wenchao Xia<xiawenc(a)linux.vnet.ibm.com>
> Sent by: libvirt-cim-bounces(a)redhat.com
>
> 01/18/2012 01:42 AM
>
> Please respond to
> List for discussion and development of libvirt CIM
<libvirt-cim(a)redhat.com>
>
> To
>
> libvirt-cim(a)redhat.com
>
> cc
>
> Wenchao Xia<xiawenc(a)cn.ibm.com>
>
> Subject
>
> [Libvirt-cim] [V4 PATCH 3/8] vlan library - add a simple
> implemention for bridge
>
> This patch use ioctl to get bridge settings from kernel. Netlink
protocol
> can't be used for bridge in linux2.6 kernel.
> ioctl is the oldest way to talk to kernel about bridge, so it have
some
> limit in the ports number and bridge number. Currently they are set to
1024.
>
> Signed-off-by: Wenchao Xia<xiawenc(a)cn.ibm.com>
> ---
> libnetwork/host_network_implement_bridge.c | 224 +++++++++++++++++
> +++++++++++
> libnetwork/host_network_implement_bridge.h | 8 +
> 2 files changed, 232 insertions(+), 0 deletions(-)
> create mode 100644 libnetwork/host_network_implement_bridge.c
> create mode 100644 libnetwork/host_network_implement_bridge.h
>
> diff --git a/libnetwork/host_network_implement_bridge.c b/
> libnetwork/host_network_implement_bridge.c
> new file mode 100644
> index 0000000..39c6b13
> --- /dev/null
> +++ b/libnetwork/host_network_implement_bridge.c
> @@ -0,0 +1,224 @@
> +/*
> + * Copyright IBM Corp. 2012
> + *
> + * Authors:
> + * Wenchao Xia<xiawenc(a)cn.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + */
> +
> +#include<stdio.h>
> +#include<stdlib.h>
> +#include<unistd.h>
> +#include<errno.h>
> +#include<string.h>
> +#include<dirent.h>
> +#include<sys/types.h>
> +#include<sys/stat.h>
> +#include<net/if.h>
> +#include<linux/if_bridge.h>
> +#include<sys/ioctl.h>
> +
> +#include "host_network_implement_bridge.h"
> +#include "host_network_helper.h"
> +#include "host_network_error.h"
> +
> +/* following number can't be changed otherwise ioctl get errors */
> +#define BR_NUM_MAX 1024
> +#define PORT_NUM_MAX 1024
> +#define NAME_BUFF_SIZE 16
> +
> +static int socket_br = -1;
> +
> +static int try_socket_init(void)
> +{
> + if (socket_br< 0) {
> + if ((socket_br = socket(AF_LOCAL, SOCK_STREAM, 0))< 0)
> + return -errno;
Why return -errno?
my mistake, errno did not need to be returned.
> + }
> + return 1;
> +}
> +
> +void try_socket_close(void)
> +{
> + if (socket_br> 0) {
> + close(socket_br);
> + socket_br = -1;
> + }
> +}
> +
> +static int get_bridge_ports(EthIface *piface)
> +{
> + struct ifreq req;
> + char ifname[NAME_BUFF_SIZE];
> + int if_indexes[PORT_NUM_MAX];
> + unsigned long args[4];
> + int i, ret = ERR_LIBBR;
> + BR_Prop *pbr;
> +
> + memset(ifname, 0, sizeof(ifname));
> + memset(&req, 0 ,sizeof(req));
> + memset(if_indexes, 0 ,sizeof(if_indexes));
> + args[0] = BRCTL_GET_PORT_LIST;
> + args[1] = (unsigned long)if_indexes;
> + args[2] = PORT_NUM_MAX;
> + args[3] = 0;
> +
> + strncpy(req.ifr_name, piface->name, NAME_BUFF_SIZE);
> + req.ifr_data = (char *)&args;
> +
> + if (0> ioctl(socket_br, SIOCDEVPRIVATE,&req)) {
convention used by libvirt-cim is - if (ioctl(socket_br, SIOCDEVPRIVATE,
&req)> 0) {
right.
> + CU_DEBUG("failed in ioctl listing ports of bridge
%s,"
> + " errno %d, reason %s.",
> + piface->name, errno, strerror(errno));
> + goto out;
> + }
> +
> + if (piface->pbr_prop == NULL) {
> + eth_iface_add_br_prop(piface);
> + }
> + pbr = piface->pbr_prop;
> +
> + i = -1;
> + while (i< PORT_NUM_MAX) {
> + i++;
> + if (if_indexes[i]<= 0) {
> + continue;
> + }
> + if (0 == if_indextoname(if_indexes[i], ifname)) {
same as above
> + CU_DEBUG("failed to translate if_index %d, skip it.",
if_indexes);
> + continue;
> + }
> + /* add the ports to the list */
> + if (pbr->port_names == NULL) {
> + SAFE_CALLOC(pbr->port_names,
> + MAX_IFACE_NUM, sizeof(char *));
Where do we free this memory?
the pointer have beed added to struct EthIface, so un-init function
of EthIface would free it.
> + pbr->port_num = 0;
> + }
> + if (pbr->port_num>= MAX_IFACE_NUM) {
> + CU_DEBUG("bridge [%s] have too much eth attached!",
> piface->name);
> + ret = ERR_DEVICE_EXCEED_MAXNUM;
> + goto out;
> + }
> + pbr->port_names[pbr->port_num] = SAFE_STRDUP(ifname);
> + pbr->port_num++;
> + }
> +
> + ret = 1;
> +
> + out:
> + return ret;
> +}
> +
> +static int get_bridge_info(EthIface *piface)
> +{
> + struct ifreq req;
> + struct __bridge_info binfo;
> + unsigned long args[4];
> + int ret = ERR_LIBBR;
> +
> + memset(&req, 0, sizeof(req));
> + memset(&binfo, 0, sizeof(binfo));
> + args[0] = BRCTL_GET_BRIDGE_INFO;
> + args[1] = (unsigned long)&binfo;
> + args[2] = 0;
> + args[3] = 0;
> + req.ifr_data = (char *)&args;
> +
> + if (piface->name == NULL) {
> + CU_DEBUG("bridge name not set for ioctl.");
> + goto out;
> + }
> + strncpy(req.ifr_name, piface->name, NAME_BUFF_SIZE);
> + if (ioctl(socket_br, SIOCDEVPRIVATE,&req)< 0) {
> + CU_DEBUG("failed to get info for %s, errno %d, reason %s.",
> + piface->name, errno, strerror(errno));
> + goto out;
> + }
> +
> + if (piface->pbr_prop == NULL) {
> + eth_iface_add_br_prop(piface);
> + }
> + piface->pbr_prop->STP = binfo.stp_enabled;
> +
> + ret = 1;
> +
> + out:
> + return ret;
> +}
> +
> +static int list_bridges(EthIfacesList *plist)
> +{
> + int if_indexes[BR_NUM_MAX];
> + unsigned long args[3];
> + int brnum;
> + int i, ret = ERR_LIBBR;
> + EthIface tface;
> +
> + eth_iface_init(&tface);
> + SAFE_CALLOC(tface.name, NAME_BUFF_SIZE, 1);
free?
> +
> + args[0] = BRCTL_GET_BRIDGES;
> + args[1] = (unsigned long)if_indexes;
> + args[2] = BR_NUM_MAX;
> + memset(if_indexes, 0, sizeof(if_indexes));
> +
> + if (0> try_socket_init()) {
convention
> + CU_DEBUG("failed to init socket for bridge ioctl,"
> + " errno is %d, reason: %s.",
> + errno, strerror(errno));
> + goto out;
> + }
> +
> + brnum = ioctl(socket_br, SIOCGIFBR, args);
> + if (brnum< 0) {
> + CU_DEBUG("failed tp get bridge, errno is %d, reason: %s.",
> + errno, strerror(errno));
> + goto out;
> + }
> +
> + i = 0;
> + while (i< brnum) {
> + if (!if_indextoname(if_indexes[i], tface.name)) {
> + CU_DEBUG("failed to translate index %d, errno is %d,
> reason: %s.",
> + if_indexes[i], errno, strerror(errno));
> + goto out;
> + }
> +
> + ret = get_bridge_info(&tface);
> + if (ret != 1) {
> + CU_DEBUG("failed to get info for %s.", tface.name);
> + continue;
> + }
> +
> + ret = get_bridge_ports(&tface);
> + if (ret != 1) {
> + CU_DEBUG("failed to get info for %s.", tface.name);
> + continue;
> + }
> +
> + if (1 != eth_ifaceslist_add(plist,&tface)) {
convention
> + CU_DEBUG("failed to add device to list.");
> + goto out;
> + }
> + eth_iface_uninit(&tface);
> + eth_iface_init(&tface);
> + SAFE_CALLOC(tface.name, NAME_BUFF_SIZE, 1);
free?
> + i++;
> + }
> + ret = 1;
> +
> + out:
> + eth_iface_uninit(&tface);
> + try_socket_close();
> + return ret;
> +
> +}
> +
> +int get_host_eth_ifaces_osapi_bridge(EthIfacesList *plist)
> +{
> + return list_bridges(plist);
> +}
> diff --git a/libnetwork/host_network_implement_bridge.h b/
> libnetwork/host_network_implement_bridge.h
> new file mode 100644
> index 0000000..ed77195
> --- /dev/null
> +++ b/libnetwork/host_network_implement_bridge.h
> @@ -0,0 +1,8 @@
> +#ifndef HOST_NETWORK_IMPLE_BRIDGE_H
> +#define HOST_NETWORK_IMPLE_BRIDGE_H
> +
> +#include "host_network_basic.h"
> +
> +int get_host_eth_ifaces_osapi_bridge(EthIfacesList *plist);
> +
> +#endif
> --
> 1.7.1
>
>
> _______________________________________________
> Libvirt-cim mailing list
> Libvirt-cim(a)redhat.com
>
https://www.redhat.com/mailman/listinfo/libvirt-cim
>
_______________________________________________
Libvirt-cim mailing list
Libvirt-cim(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvirt-cim
--
Best Regards
Wayne Xia
mail:xiawenc@linux.vnet.ibm.com
tel:86-010-82450803