| 1 | --- a/br2684ctl.c |
| 2 | +++ b/br2684ctl.c |
| 3 | @@ -10,6 +10,10 @@ |
| 4 | #include <atm.h> |
| 5 | #include <linux/atmdev.h> |
| 6 | #include <linux/atmbr2684.h> |
| 7 | +#ifndef BR2684_FLAG_ROUTED |
| 8 | +#warning "Kernel missing routed support for br2684" |
| 9 | +#define BR2684_FLAG_ROUTED (1<<16) /* payload is routed, not bridged */ |
| 10 | +#endif |
| 11 | |
| 12 | /* Written by Marcell GAL <cell@sch.bme.hu> to make use of the */ |
| 13 | /* ioctls defined in the br2684... kernel patch */ |
| 14 | @@ -28,26 +32,35 @@ |
| 15 | #define LOG_OPTION LOG_PERROR|LOG_PID |
| 16 | #define LOG_FACILITY LOG_LOCAL2 |
| 17 | |
| 18 | +struct br2684_params { |
| 19 | + int itfnum; |
| 20 | + int encap; |
| 21 | + int sndbuf; |
| 22 | + int payload; |
| 23 | + char *astr; /* temporary */ |
| 24 | + struct atm_qos reqqos; |
| 25 | +}; |
| 26 | + |
| 27 | |
| 28 | int lastsock, lastitf; |
| 29 | |
| 30 | |
| 31 | -void fatal(const char *str, int i) |
| 32 | +void fatal(const char *str, int err) |
| 33 | { |
| 34 | - syslog (LOG_ERR,"Fatal: %s",str); |
| 35 | + syslog (LOG_ERR,"Fatal: %s; %s", str, strerror(err)); |
| 36 | exit(-2); |
| 37 | }; |
| 38 | |
| 39 | |
| 40 | void exitFunc(void) |
| 41 | { |
| 42 | - syslog (LOG_NOTICE,"Daemon terminated\n"); |
| 43 | + syslog (LOG_NOTICE,"Daemon terminated"); |
| 44 | } |
| 45 | |
| 46 | |
| 47 | void int_signal(int dummy) |
| 48 | { |
| 49 | - syslog (LOG_INFO,"Killed by a signal\n"); |
| 50 | + syslog (LOG_INFO,"Killed by a signal"); |
| 51 | exit(0); |
| 52 | } |
| 53 | |
| 54 | @@ -58,7 +71,7 @@ int create_pidfile(int num) |
| 55 | |
| 56 | if (num < 0) return -1; |
| 57 | |
| 58 | - snprintf(name, 20, "/var/run/nas%d.pid", num); |
| 59 | + snprintf(name, 32, "/var/run/br2684ctl-nas%d.pid", num); |
| 60 | pidfile = fopen(name, "w"); |
| 61 | if (pidfile == NULL) return -1; |
| 62 | fprintf(pidfile, "%d", getpid()); |
| 63 | @@ -67,9 +80,9 @@ int create_pidfile(int num) |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | -int create_br(char *nstr) |
| 68 | +int create_br(int itfnum, int payload) |
| 69 | { |
| 70 | - int num, err; |
| 71 | + int err; |
| 72 | |
| 73 | if(lastsock<0) { |
| 74 | lastsock = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); |
| 75 | @@ -78,31 +91,36 @@ int create_br(char *nstr) |
| 76 | syslog(LOG_ERR, "socket creation failed: %s",strerror(errno)); |
| 77 | } else { |
| 78 | /* create the device with ioctl: */ |
| 79 | - num=atoi(nstr); |
| 80 | - if( num>=0 && num<1234567890){ |
| 81 | + if( itfnum>=0 && itfnum<1234567890){ |
| 82 | struct atm_newif_br2684 ni; |
| 83 | ni.backend_num = ATM_BACKEND_BR2684; |
| 84 | ni.media = BR2684_MEDIA_ETHERNET; |
| 85 | +#ifdef BR2684_FLAG_ROUTED |
| 86 | + if (payload == 0) |
| 87 | + ni.media |= BR2684_FLAG_ROUTED; |
| 88 | +#endif |
| 89 | ni.mtu = 1500; |
| 90 | - sprintf(ni.ifname, "nas%d", num); |
| 91 | + sprintf(ni.ifname, "nas%d", itfnum); |
| 92 | err=ioctl (lastsock, ATM_NEWBACKENDIF, &ni); |
| 93 | |
| 94 | if (err == 0) |
| 95 | - syslog(LOG_NOTICE, "Interface \"%s\" created sucessfully\n",ni.ifname); |
| 96 | + syslog(LOG_NOTICE, "Interface \"%s\" created sucessfully",ni.ifname); |
| 97 | else |
| 98 | - syslog(LOG_INFO, "Interface \"%s\" could not be created, reason: %s\n", |
| 99 | + syslog(LOG_INFO, "Interface \"%s\" could not be created, reason: %s", |
| 100 | ni.ifname, |
| 101 | strerror(errno)); |
| 102 | - lastitf=num; /* even if we didn't create, because existed, assign_vcc wil want to know it! */ |
| 103 | + lastitf=itfnum; /* even if we didn't create, because existed, |
| 104 | + assign_vcc wil want to know it! */ |
| 105 | } else { |
| 106 | - syslog(LOG_ERR,"err: strange interface number %d", num ); |
| 107 | + syslog(LOG_ERR,"err: strange interface number %d", itfnum ); |
| 108 | } |
| 109 | } |
| 110 | return 0; |
| 111 | } |
| 112 | |
| 113 | |
| 114 | -int assign_vcc(char *astr, int encap, int bufsize, struct atm_qos qos) |
| 115 | +int assign_vcc(char *astr, int encap, int payload, |
| 116 | + int bufsize, struct atm_qos qos) |
| 117 | { |
| 118 | int err; |
| 119 | struct sockaddr_atmpvc addr; |
| 120 | @@ -112,21 +130,17 @@ int assign_vcc(char *astr, int encap, in |
| 121 | memset(&addr, 0, sizeof(addr)); |
| 122 | err=text2atm(astr,(struct sockaddr *)(&addr), sizeof(addr), T2A_PVC); |
| 123 | if (err!=0) |
| 124 | - syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)\n",err); |
| 125 | + syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)",err); |
| 126 | |
| 127 | -#if 0 |
| 128 | - addr.sap_family = AF_ATMPVC; |
| 129 | - addr.sap_addr.itf = itf; |
| 130 | - addr.sap_addr.vpi = 0; |
| 131 | - addr.sap_addr.vci = vci; |
| 132 | -#endif |
| 133 | - syslog(LOG_NOTICE,"Communicating over ATM %d.%d.%d, encapsulation: %s\n", addr.sap_addr.itf, |
| 134 | + syslog(LOG_NOTICE,"Communicating over ATM %d.%d.%d, encapsulation: %s", |
| 135 | + addr.sap_addr.itf, |
| 136 | addr.sap_addr.vpi, |
| 137 | addr.sap_addr.vci, |
| 138 | encap?"VC mux":"LLC"); |
| 139 | |
| 140 | if ((fd = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5)) < 0) |
| 141 | - syslog(LOG_ERR,"failed to create socket %d, reason: %s", errno,strerror(errno)); |
| 142 | + syslog(LOG_ERR,"failed to create socket %d, reason: %s", |
| 143 | + errno,strerror(errno)); |
| 144 | |
| 145 | if (qos.aal == 0) { |
| 146 | qos.aal = ATM_AAL5; |
| 147 | @@ -137,7 +151,7 @@ int assign_vcc(char *astr, int encap, in |
| 148 | } |
| 149 | |
| 150 | if ( (err=setsockopt(fd,SOL_SOCKET,SO_SNDBUF, &bufsize ,sizeof(bufsize))) ) |
| 151 | - syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s\n",err, strerror(err)); |
| 152 | + syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s",err, strerror(err)); |
| 153 | |
| 154 | if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) |
| 155 | syslog(LOG_ERR,"setsockopt SO_ATMQOS %d", errno); |
| 156 | @@ -145,7 +159,7 @@ int assign_vcc(char *astr, int encap, in |
| 157 | err = connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_atmpvc)); |
| 158 | |
| 159 | if (err < 0) |
| 160 | - fatal("failed to connect on socket", err); |
| 161 | + fatal("failed to connect on socket", errno); |
| 162 | |
| 163 | /* attach the vcc to device: */ |
| 164 | |
| 165 | @@ -169,10 +183,30 @@ int assign_vcc(char *astr, int encap, in |
| 166 | return fd ; |
| 167 | } |
| 168 | |
| 169 | +void start_interface(struct br2684_params* params) |
| 170 | +{ |
| 171 | + if (params->astr==NULL) { |
| 172 | + syslog(LOG_ERR, "Required ATM parameters not specified."); |
| 173 | + exit(1); |
| 174 | + } |
| 175 | + |
| 176 | + create_br(params->itfnum, params->payload); |
| 177 | + assign_vcc(params->astr, params->encap, params->payload, params->sndbuf, |
| 178 | + params->reqqos); |
| 179 | +} |
| 180 | + |
| 181 | |
| 182 | void usage(char *s) |
| 183 | { |
| 184 | - printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-a [itf.]vpi.vci]*]*\n", s); |
| 185 | + printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-p 0|1] " |
| 186 | + "[-a [itf.]vpi.vci]*]*\n" |
| 187 | + " -b = run in background (daemonize)\n" |
| 188 | + " -c <num> = use interface nas<num>\n" |
| 189 | + " -e 0|1 = encapsulation (0=LLC, 1=VC Mux)\n" |
| 190 | + " -p 0|1 = payload type (0=routed,1=bridged)\n" |
| 191 | + " -s <num> = set sndbuf (send buffer) size (default 8192)\n" |
| 192 | + " -a [itf.]vpi.vci = ATM interface no, VPI, VCI\n", |
| 193 | + s); |
| 194 | exit(1); |
| 195 | } |
| 196 | |
| 197 | @@ -180,47 +214,63 @@ void usage(char *s) |
| 198 | |
| 199 | int main (int argc, char **argv) |
| 200 | { |
| 201 | - int c, background=0, encap=0, sndbuf=8192; |
| 202 | - struct atm_qos reqqos; |
| 203 | - int itfnum; |
| 204 | + int c, background=0; |
| 205 | + |
| 206 | + struct br2684_params params; |
| 207 | + params.itfnum=-1; |
| 208 | + params.encap=0; |
| 209 | + params.sndbuf=8192; |
| 210 | + params.payload=1; |
| 211 | + params.astr=NULL; |
| 212 | + memset(¶ms.reqqos, 0, sizeof(params.reqqos)); |
| 213 | + |
| 214 | lastsock=-1; |
| 215 | lastitf=0; |
| 216 | |
| 217 | /* st qos to 0 */ |
| 218 | - memset(&reqqos, 0, sizeof(reqqos)); |
| 219 | |
| 220 | openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY); |
| 221 | if (argc>1) |
| 222 | - while ((c = getopt(argc, argv,"q:a:bc:e:s:?h")) !=EOF) |
| 223 | + while ((c = getopt(argc, argv,"q:a:bc:e:s:p:?h")) !=EOF) |
| 224 | switch (c) { |
| 225 | case 'q': |
| 226 | printf ("optarg : %s",optarg); |
| 227 | - if (text2qos(optarg,&reqqos,0)) fprintf(stderr,"QOS parameter invalid\n"); |
| 228 | + if (text2qos(optarg,¶ms.reqqos,0)) |
| 229 | + fprintf(stderr,"QOS parameter invalid\n"); |
| 230 | break; |
| 231 | case 'a': |
| 232 | - assign_vcc(optarg, encap, sndbuf, reqqos); |
| 233 | + params.astr=optarg; |
| 234 | break; |
| 235 | case 'b': |
| 236 | background=1; |
| 237 | break; |
| 238 | case 'c': |
| 239 | - create_br(optarg); |
| 240 | - itfnum = atoi(optarg); |
| 241 | + /* temporary, to make it work with multiple interfaces: */ |
| 242 | + if (params.itfnum>=0) start_interface(¶ms); |
| 243 | + params.itfnum= atoi(optarg); |
| 244 | break; |
| 245 | case 'e': |
| 246 | - encap=(atoi(optarg)); |
| 247 | - if(encap<0){ |
| 248 | - syslog (LOG_ERR, "invalid encapsulation: %s:\n",optarg); |
| 249 | - encap=0; |
| 250 | + params.encap=(atoi(optarg)); |
| 251 | + if(params.encap<0){ |
| 252 | + syslog (LOG_ERR, "invalid encapsulation: %s:",optarg); |
| 253 | + params.encap=0; |
| 254 | } |
| 255 | break; |
| 256 | case 's': |
| 257 | - sndbuf=(atoi(optarg)); |
| 258 | - if(sndbuf<0){ |
| 259 | - syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead\n",optarg); |
| 260 | - sndbuf=8192; |
| 261 | + params.sndbuf=(atoi(optarg)); |
| 262 | + if(params.sndbuf<0){ |
| 263 | + syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead", |
| 264 | + optarg); |
| 265 | + params.sndbuf=8192; |
| 266 | } |
| 267 | break; |
| 268 | + case 'p': /* payload type: routed (0) or bridged (1) */ |
| 269 | +#ifdef BR2684_FLAG_ROUTED |
| 270 | + params.payload = atoi(optarg); |
| 271 | + break; |
| 272 | +#else |
| 273 | + syslog(LOG_ERR, "payload option not supported."); |
| 274 | +#endif |
| 275 | case '?': |
| 276 | case 'h': |
| 277 | default: |
| 278 | @@ -231,6 +281,8 @@ int main (int argc, char **argv) |
| 279 | |
| 280 | if (argc != optind) usage(argv[0]); |
| 281 | |
| 282 | + start_interface(¶ms); |
| 283 | + |
| 284 | if(lastsock>=0) close(lastsock); |
| 285 | |
| 286 | if (background) { |
| 287 | @@ -268,11 +320,11 @@ int main (int argc, char **argv) |
| 288 | |
| 289 | } |
| 290 | |
| 291 | - create_pidfile(itfnum); |
| 292 | + create_pidfile(params.itfnum); |
| 293 | signal(SIGINT, int_signal); |
| 294 | signal(SIGTERM, int_signal); |
| 295 | |
| 296 | - syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started\n"); |
| 297 | + syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started"); |
| 298 | atexit (exitFunc); |
| 299 | |
| 300 | while (1) pause(); /* to keep the sockets... */ |
| 301 | |