A R Karthick | edab01c | 2016-09-08 14:05:44 -0700 | [diff] [blame] | 1 | diff --git a/cbench/cbench.c b/cbench/cbench.c |
| 2 | index 70fed93..cdf8492 100644 |
| 3 | --- a/cbench/cbench.c |
| 4 | +++ b/cbench/cbench.c |
| 5 | @@ -45,6 +45,7 @@ struct myargs my_options[] = { |
| 6 | {"connect-group-size", 'I', "number of switches in a connection delay group", MYARGS_INTEGER, {.integer = 1}}, |
| 7 | {"learn-dst-macs", 'L', "send gratuitious ARP replies to learn destination macs before testing", MYARGS_FLAG, {.flag = 1}}, |
| 8 | {"dpid-offset", 'o', "switch DPID offset", MYARGS_INTEGER, {.integer = 1}}, |
| 9 | + {"igmp-test", 'g', "IGMP join leave test", MYARGS_FLAG, {.flag = 0}}, |
| 10 | {0, 0, 0, 0} |
| 11 | }; |
| 12 | |
| 13 | @@ -257,6 +258,7 @@ int main(int argc, char * argv[]) |
| 14 | int learn_dst_macs = myargs_get_default_flag(my_options, "learn-dst-macs"); |
| 15 | int dpid_offset = myargs_get_default_integer(my_options, "dpid-offset"); |
| 16 | int mode = MODE_LATENCY; |
| 17 | + int igmp_test = myargs_get_default_flag(my_options, "igmp-test"); |
| 18 | int i,j; |
| 19 | |
| 20 | const struct option * long_opts = myargs_to_long(my_options); |
| 21 | @@ -326,6 +328,9 @@ int main(int argc, char * argv[]) |
| 22 | case 'o': |
| 23 | dpid_offset = atoi(optarg); |
| 24 | break; |
| 25 | + case 'g': |
| 26 | + igmp_test = 1; |
| 27 | + break; |
| 28 | default: |
| 29 | myargs_usage(my_options, PROG_TITLE, "help message", NULL, 1); |
| 30 | } |
| 31 | @@ -388,7 +393,8 @@ int main(int argc, char * argv[]) |
| 32 | if(debug) |
| 33 | fprintf(stderr,"Initializing switch %d ... ", i+1); |
| 34 | fflush(stderr); |
| 35 | - fakeswitch_init(&fakeswitches[i],dpid_offset+i,sock,BUFLEN, debug, delay, mode, total_mac_addresses, learn_dst_macs); |
| 36 | + fakeswitch_init(&fakeswitches[i],dpid_offset+i,sock,BUFLEN, debug, delay, mode, total_mac_addresses, |
| 37 | + learn_dst_macs, igmp_test); |
| 38 | if(debug) |
| 39 | fprintf(stderr," :: done.\n"); |
| 40 | fflush(stderr); |
| 41 | diff --git a/cbench/fakeswitch.c b/cbench/fakeswitch.c |
| 42 | index a424d14..d3f16de 100644 |
| 43 | --- a/cbench/fakeswitch.c |
| 44 | +++ b/cbench/fakeswitch.c |
| 45 | @@ -25,12 +25,14 @@ static int make_stats_desc_reply(struct ofp_stats_request * req, char * buf, int |
| 46 | static int parse_set_config(struct ofp_header * msg); |
| 47 | static int make_config_reply( int xid, char * buf, int buflen); |
| 48 | static int make_vendor_reply(int xid, char * buf, int buflen); |
| 49 | -static int make_packet_in(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address); |
| 50 | static int packet_out_is_lldp(struct ofp_packet_out * po); |
| 51 | static void fakeswitch_handle_write(struct fakeswitch *fs); |
| 52 | static void fakeswitch_learn_dstmac(struct fakeswitch *fs); |
| 53 | void fakeswitch_change_status_now (struct fakeswitch *fs, int new_status); |
| 54 | void fakeswitch_change_status (struct fakeswitch *fs, int new_status); |
| 55 | +static int make_packet_in_default(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address); |
| 56 | +static int make_packet_in_igmp(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address); |
| 57 | +static int (*make_packet_in)(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address); |
| 58 | |
| 59 | static struct ofp_switch_config Switch_config = { |
| 60 | .header = { OFP_VERSION, |
| 61 | @@ -51,7 +53,7 @@ static inline uint64_t ntohll(uint64_t n) |
| 62 | return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32); |
| 63 | } |
| 64 | |
| 65 | -void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int debug, int delay, enum test_mode mode, int total_mac_addresses, int learn_dstmac) |
| 66 | +void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int debug, int delay, enum test_mode mode, int total_mac_addresses, int learn_dstmac, int igmp_test) |
| 67 | { |
| 68 | char buf[BUFLEN]; |
| 69 | struct ofp_header ofph; |
| 70 | @@ -62,6 +64,8 @@ void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int |
| 71 | fs->outbuf = msgbuf_new(bufsize); |
| 72 | fs->probe_state = 0; |
| 73 | fs->mode = mode; |
| 74 | + fs->igmp_test = igmp_test; |
| 75 | + make_packet_in = igmp_test ? make_packet_in_igmp : make_packet_in_default; |
| 76 | fs->probe_size = make_packet_in(fs->id, 0, 0, buf, BUFLEN, fs->current_mac_address++); |
| 77 | fs->count = 0; |
| 78 | fs->switch_status = START; |
| 79 | @@ -71,7 +75,6 @@ void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int |
| 80 | fs->xid = 1; |
| 81 | fs->learn_dstmac = learn_dstmac; |
| 82 | fs->current_buffer_id = 1; |
| 83 | - |
| 84 | ofph.version = OFP_VERSION; |
| 85 | ofph.type = OFPT_HELLO; |
| 86 | ofph.length = htons(sizeof(ofph)); |
| 87 | @@ -289,8 +292,54 @@ static int packet_out_is_lldp(struct ofp_packet_out * po){ |
| 88 | return ethertype == ETHERTYPE_LLDP; |
| 89 | } |
| 90 | |
| 91 | +static int make_packet_in_igmp(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address) |
| 92 | +{ |
| 93 | + struct ofp_packet_in * pi; |
| 94 | + struct ether_header * eth; |
| 95 | + static char fake_igmp_join[] = { |
| 96 | + 0x97,0x0a,0x00,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| 97 | + 0x01,0x00,0x40,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00, |
| 98 | + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x08,0x00,0x46, |
| 99 | + 0xc0,0x00,0x2c,0x00,0x01,0x00,0x00,0x01,0x02,0x3f,0x04, |
| 100 | + 0x01,0x02,0x03,0x04,0xe0,0x00,0x01,0x01,0x94,0x04,0x00, |
| 101 | + 0x00,0x22,0x00,0xf6,0xf5,0x00,0x00,0x00,0x01,0x01,0x00, |
| 102 | + 0x00,0x01,0xe2,0x00,0x00,0x01,0x01,0x02,0x03,0x04, |
| 103 | + }; |
| 104 | + static char fake_igmp_leave[] = { |
| 105 | + 0x97,0x0a,0x00,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| 106 | + 0x01,0x00,0x40,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00, |
| 107 | + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x08,0x00,0x46, |
| 108 | + 0xc0,0x00,0x2c,0x00,0x01,0x00,0x00,0x01,0x02,0x3f,0x04, |
| 109 | + 0x01,0x02,0x03,0x04,0xe0,0x00,0x01,0x01,0x94,0x04,0x00, |
| 110 | + 0x00,0x22,0x00,0xf5,0xf5,0x00,0x00,0x00,0x01,0x02,0x00, |
| 111 | + 0x00,0x01,0xe2,0x00,0x00,0x01,0x01,0x02,0x03,0x04, |
| 112 | + }; |
| 113 | + static char *fake_bufs[2] = { fake_igmp_join, fake_igmp_leave }; |
| 114 | + static int fake_size_map[2] = { (int)sizeof(fake_igmp_join), (int)sizeof(fake_igmp_leave) }; |
| 115 | + static int idx; |
| 116 | + int cur_idx = idx; |
| 117 | + int buf_size = fake_size_map[cur_idx]; |
| 118 | + char *fake; |
| 119 | + fake = fake_bufs[cur_idx]; |
| 120 | + idx ^= 1; |
| 121 | + assert(buflen > buf_size); |
| 122 | + memcpy(buf, fake, buf_size); |
| 123 | + pi = (struct ofp_packet_in *) buf; |
| 124 | + pi->header.version = OFP_VERSION; |
| 125 | + pi->header.xid = htonl(xid); |
| 126 | + pi->buffer_id = htonl(buffer_id); |
| 127 | + eth = (struct ether_header * ) pi->data; |
| 128 | + // copy into src mac addr; only 4 bytes, but should suffice to not confuse |
| 129 | + // the controller; don't overwrite first byte |
| 130 | + memcpy(ð->ether_shost[1], &mac_address, sizeof(mac_address)); |
| 131 | + // mark this as coming from us, mostly for debug |
| 132 | + eth->ether_dhost[5] = switch_id; |
| 133 | + eth->ether_shost[5] = switch_id; |
| 134 | + return buf_size; |
| 135 | +} |
| 136 | + |
| 137 | /***********************************************************************/ |
| 138 | -static int make_packet_in(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address) |
| 139 | +static int make_packet_in_default(int switch_id, int xid, int buffer_id, char * buf, int buflen, int mac_address) |
| 140 | { |
| 141 | struct ofp_packet_in * pi; |
| 142 | struct ether_header * eth; |
| 143 | @@ -387,6 +436,7 @@ void fakeswitch_handle_read(struct fakeswitch *fs) |
| 144 | if(fs->switch_status == READY_TO_SEND && (fm->command == htons(OFPFC_ADD) || |
| 145 | fm->command == htons(OFPFC_MODIFY_STRICT))) |
| 146 | { |
| 147 | + debug_msg(fs, "Got FLOW MOD response\n"); |
| 148 | fs->count++; // got response to what we went |
| 149 | fs->probe_state--; |
| 150 | } |
| 151 | @@ -488,6 +538,7 @@ static void fakeswitch_handle_write(struct fakeswitch *fs) |
| 152 | else if ((fs->mode == MODE_THROUGHPUT) && |
| 153 | (msgbuf_count_buffered(fs->outbuf) < throughput_buffer)) // keep buffer full |
| 154 | send_count = (throughput_buffer - msgbuf_count_buffered(fs->outbuf)) / fs->probe_size; |
| 155 | + |
| 156 | for (i = 0; i < send_count; i++) |
| 157 | { |
| 158 | // queue up packet |
| 159 | diff --git a/cbench/fakeswitch.h b/cbench/fakeswitch.h |
| 160 | index d0352e7..26eb202 100644 |
| 161 | --- a/cbench/fakeswitch.h |
| 162 | +++ b/cbench/fakeswitch.h |
| 163 | @@ -39,6 +39,7 @@ struct fakeswitch |
| 164 | int current_mac_address; |
| 165 | int learn_dstmac; |
| 166 | int current_buffer_id; |
| 167 | + int igmp_test; |
| 168 | }; |
| 169 | |
| 170 | /*** Initialize an already allocated fakeswitch |
| 171 | @@ -54,7 +55,7 @@ struct fakeswitch |
| 172 | * @param total_mac_addresses The total number of unique mac addresses |
| 173 | * to use for packet ins from this switch |
| 174 | */ |
| 175 | -void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int debug, int delay, enum test_mode mode, int total_mac_addresses, int learn_dstmac); |
| 176 | +void fakeswitch_init(struct fakeswitch *fs, int dpid, int sock, int bufsize, int debug, int delay, enum test_mode mode, int total_mac_addresses, int learn_dstmac, int igmp_test); |
| 177 | |
| 178 | |
| 179 | /*** Set the desired flags for poll() |