1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation. 3 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org> 4 * All rights reserved. 5 */ 6 7 #include <stdio.h> 8 #include <stdint.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <errno.h> 12 13 #include <cmdline_rdline.h> 14 #include <cmdline_parse.h> 15 #include <cmdline_parse_ipaddr.h> 16 #include <cmdline_parse_num.h> 17 #include <cmdline_parse_string.h> 18 #include <cmdline.h> 19 20 #include <rte_string_fns.h> 21 22 #include "parse_obj_list.h" 23 24 struct object_list global_obj_list; 25 26 /* not defined under linux */ 27 #ifndef NIPQUAD 28 #define NIPQUAD_FMT "%u.%u.%u.%u" 29 #define NIPQUAD(addr) \ 30 (unsigned)((unsigned char *)&addr)[0], \ 31 (unsigned)((unsigned char *)&addr)[1], \ 32 (unsigned)((unsigned char *)&addr)[2], \ 33 (unsigned)((unsigned char *)&addr)[3] 34 #endif 35 36 /**********************************************************/ 37 38 /* Show or delete tokens. 8< */ 39 struct cmd_obj_del_show_result { 40 cmdline_fixed_string_t action; 41 struct object *obj; 42 }; 43 44 static void cmd_obj_del_show_parsed(void *parsed_result, 45 struct cmdline *cl, 46 __rte_unused void *data) 47 { 48 struct cmd_obj_del_show_result *res = parsed_result; 49 char ip_str[INET6_ADDRSTRLEN]; 50 51 if (res->obj->ip.family == AF_INET) 52 snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT, 53 NIPQUAD(res->obj->ip.addr.ipv4)); 54 else 55 snprintf(ip_str, sizeof(ip_str), RTE_IPV6_ADDR_FMT, 56 RTE_IPV6_ADDR_SPLIT(&res->obj->ip.addr.ipv6)); 57 58 if (strcmp(res->action, "del") == 0) { 59 SLIST_REMOVE(&global_obj_list, res->obj, object, next); 60 cmdline_printf(cl, "Object %s removed, ip=%s\n", 61 res->obj->name, ip_str); 62 free(res->obj); 63 } 64 else if (strcmp(res->action, "show") == 0) { 65 cmdline_printf(cl, "Object %s, ip=%s\n", 66 res->obj->name, ip_str); 67 } 68 } 69 70 cmdline_parse_token_string_t cmd_obj_action = 71 TOKEN_STRING_INITIALIZER(struct cmd_obj_del_show_result, 72 action, "show#del"); 73 parse_token_obj_list_t cmd_obj_obj = 74 TOKEN_OBJ_LIST_INITIALIZER(struct cmd_obj_del_show_result, obj, 75 &global_obj_list); 76 77 cmdline_parse_inst_t cmd_obj_del_show = { 78 .f = cmd_obj_del_show_parsed, /* function to call */ 79 .data = NULL, /* 2nd arg of func */ 80 .help_str = "Show/del an object", 81 .tokens = { /* token list, NULL terminated */ 82 (void *)&cmd_obj_action, 83 (void *)&cmd_obj_obj, 84 NULL, 85 }, 86 }; 87 /* >8 End of show or delete tokens. */ 88 89 /**********************************************************/ 90 91 struct cmd_obj_add_result { 92 cmdline_fixed_string_t action; 93 cmdline_fixed_string_t name; 94 cmdline_ipaddr_t ip; 95 }; 96 97 static void cmd_obj_add_parsed(void *parsed_result, 98 struct cmdline *cl, 99 __rte_unused void *data) 100 { 101 struct cmd_obj_add_result *res = parsed_result; 102 struct object *o; 103 char ip_str[INET6_ADDRSTRLEN]; 104 105 SLIST_FOREACH(o, &global_obj_list, next) { 106 if (!strcmp(res->name, o->name)) { 107 cmdline_printf(cl, "Object %s already exist\n", res->name); 108 return; 109 } 110 break; 111 } 112 113 o = malloc(sizeof(*o)); 114 if (!o) { 115 cmdline_printf(cl, "mem error\n"); 116 return; 117 } 118 strlcpy(o->name, res->name, sizeof(o->name)); 119 o->ip = res->ip; 120 SLIST_INSERT_HEAD(&global_obj_list, o, next); 121 122 if (o->ip.family == AF_INET) 123 snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT, 124 NIPQUAD(o->ip.addr.ipv4)); 125 else 126 snprintf(ip_str, sizeof(ip_str), RTE_IPV6_ADDR_FMT, 127 RTE_IPV6_ADDR_SPLIT(&o->ip.addr.ipv6)); 128 129 cmdline_printf(cl, "Object %s added, ip=%s\n", 130 o->name, ip_str); 131 } 132 133 cmdline_parse_token_string_t cmd_obj_action_add = 134 TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, action, "add"); 135 cmdline_parse_token_string_t cmd_obj_name = 136 TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, name, NULL); 137 cmdline_parse_token_ipaddr_t cmd_obj_ip = 138 TOKEN_IPADDR_INITIALIZER(struct cmd_obj_add_result, ip); 139 140 cmdline_parse_inst_t cmd_obj_add = { 141 .f = cmd_obj_add_parsed, /* function to call */ 142 .data = NULL, /* 2nd arg of func */ 143 .help_str = "Add an object (name, val)", 144 .tokens = { /* token list, NULL terminated */ 145 (void *)&cmd_obj_action_add, 146 (void *)&cmd_obj_name, 147 (void *)&cmd_obj_ip, 148 NULL, 149 }, 150 }; 151 152 /**********************************************************/ 153 154 struct cmd_help_result { 155 cmdline_fixed_string_t help; 156 }; 157 158 static void cmd_help_parsed(__rte_unused void *parsed_result, 159 struct cmdline *cl, 160 __rte_unused void *data) 161 { 162 cmdline_printf(cl, 163 "Demo example of command line interface in RTE\n\n" 164 "This is a readline-like interface that can be used to\n" 165 "debug your RTE application. It supports some features\n" 166 "of GNU readline like completion, cut/paste, and some\n" 167 "other special bindings.\n\n" 168 "This demo shows how rte_cmdline library can be\n" 169 "extended to handle a list of objects. There are\n" 170 "3 commands:\n" 171 "- add obj_name IP\n" 172 "- del obj_name\n" 173 "- show obj_name\n\n"); 174 } 175 176 cmdline_parse_token_string_t cmd_help_help = 177 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help"); 178 179 cmdline_parse_inst_t cmd_help = { 180 .f = cmd_help_parsed, /* function to call */ 181 .data = NULL, /* 2nd arg of func */ 182 .help_str = "show help", 183 .tokens = { /* token list, NULL terminated */ 184 (void *)&cmd_help_help, 185 NULL, 186 }, 187 }; 188 189 190 /**********************************************************/ 191 /**********************************************************/ 192 /****** CONTEXT (list of instruction) */ 193 194 /* Cmdline context list of commands in NULL-terminated table. 8< */ 195 cmdline_parse_ctx_t main_ctx[] = { 196 (cmdline_parse_inst_t *)&cmd_obj_del_show, 197 (cmdline_parse_inst_t *)&cmd_obj_add, 198 (cmdline_parse_inst_t *)&cmd_help, 199 NULL, 200 }; 201 /* >8 End of context list. */ 202