1/* 2 * $Id: libbridge_devif.c,v 1.1.1.1 2008/10/15 03:28:31 james26_jang Exp $ 3 * 4 * Copyright (C) 2000 Lennert Buytenhek 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <errno.h> 25#include <sys/fcntl.h> 26#include <sys/ioctl.h> 27#include <sys/time.h> 28#include "libbridge.h" 29#include "libbridge_private.h" 30 31int br_device_ioctl(struct bridge *br, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3) 32{ 33 unsigned long args[4]; 34 struct ifreq ifr; 35 36 args[0] = arg0; 37 args[1] = arg1; 38 args[2] = arg2; 39 args[3] = arg3; 40 41 memcpy(ifr.ifr_name, br->ifname, IFNAMSIZ); 42 ((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args; 43 44 return ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr); 45} 46 47int br_add_interface(struct bridge *br, int ifindex) 48{ 49 if (br_device_ioctl(br, BRCTL_ADD_IF, ifindex, 0, 0) < 0) 50 return errno; 51 52 return 0; 53} 54 55int br_del_interface(struct bridge *br, int ifindex) 56{ 57 if (br_device_ioctl(br, BRCTL_DEL_IF, ifindex, 0, 0) < 0) 58 return errno; 59 60 return 0; 61} 62 63int br_set_bridge_forward_delay(struct bridge *br, struct timeval *tv) 64{ 65 unsigned long jif = __tv_to_jiffies(tv); 66 67 if (br_device_ioctl(br, BRCTL_SET_BRIDGE_FORWARD_DELAY, 68 jif, 0, 0) < 0) 69 return errno; 70 71 return 0; 72} 73 74int br_set_bridge_hello_time(struct bridge *br, struct timeval *tv) 75{ 76 unsigned long jif = __tv_to_jiffies(tv); 77 78 if (br_device_ioctl(br, BRCTL_SET_BRIDGE_HELLO_TIME, jif, 0, 0) < 0) 79 return errno; 80 81 return 0; 82} 83 84int br_set_bridge_max_age(struct bridge *br, struct timeval *tv) 85{ 86 unsigned long jif = __tv_to_jiffies(tv); 87 88 if (br_device_ioctl(br, BRCTL_SET_BRIDGE_MAX_AGE, jif, 0, 0) < 0) 89 return errno; 90 91 return 0; 92} 93 94int br_set_ageing_time(struct bridge *br, struct timeval *tv) 95{ 96 unsigned long jif = __tv_to_jiffies(tv); 97 98 if (br_device_ioctl(br, BRCTL_SET_AGEING_TIME, jif, 0, 0) < 0) 99 return errno; 100 101 return 0; 102} 103 104int br_set_gc_interval(struct bridge *br, struct timeval *tv) 105{ 106 unsigned long jif = __tv_to_jiffies(tv); 107 108 if (br_device_ioctl(br, BRCTL_SET_GC_INTERVAL, jif, 0, 0) < 0) 109 return errno; 110 111 return 0; 112} 113 114int br_set_stp_state(struct bridge *br, int stp_state) 115{ 116 if (br_device_ioctl(br, BRCTL_SET_BRIDGE_STP_STATE, stp_state, 117 0, 0) < 0) 118 return errno; 119 120 return 0; 121} 122 123int br_set_bridge_priority(struct bridge *br, int bridge_priority) 124{ 125 if (br_device_ioctl(br, BRCTL_SET_BRIDGE_PRIORITY, bridge_priority, 126 0, 0) < 0) 127 return errno; 128 129 return 0; 130} 131 132int br_set_port_priority(struct port *p, int port_priority) 133{ 134 if (br_device_ioctl(p->parent, BRCTL_SET_PORT_PRIORITY, p->index, 135 port_priority, 0) < 0) 136 return errno; 137 138 return 0; 139} 140 141int br_set_path_cost(struct port *p, int path_cost) 142{ 143 if (br_device_ioctl(p->parent, BRCTL_SET_PATH_COST, p->index, 144 path_cost, 0) < 0) 145 return errno; 146 147 return 0; 148} 149 150void __copy_fdb(struct fdb_entry *ent, struct __fdb_entry *f) 151{ 152 memcpy(ent->mac_addr, f->mac_addr, 6); 153 ent->port_no = f->port_no; 154 ent->is_local = f->is_local; 155 __jiffies_to_tv(&ent->ageing_timer_value, f->ageing_timer_value); 156} 157 158int br_read_fdb(struct bridge *br, struct fdb_entry *fdbs, int offset, int num) 159{ 160 struct __fdb_entry f[num]; 161 int i; 162 int numread; 163 164 if ((numread = br_device_ioctl(br, BRCTL_GET_FDB_ENTRIES, 165 (unsigned long)f, num, offset)) < 0) 166 return errno; 167 168 for (i=0;i<numread;i++) 169 __copy_fdb(fdbs+i, f+i); 170 171 return numread; 172} 173