00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <netlink-local.h>
00020 #include <netlink-tc.h>
00021 #include <netlink/netlink.h>
00022 #include <netlink/route/cls/ematch.h>
00023 #include <netlink/route/cls/ematch/text.h>
00024
00025 struct text_data
00026 {
00027 struct tcf_em_text cfg;
00028 char * pattern;
00029 };
00030
00031 void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
00032 uint16_t offset)
00033 {
00034 struct text_data *t = rtnl_ematch_data(e);
00035 t->cfg.from_offset = offset;
00036 t->cfg.from_layer = layer;
00037 }
00038
00039 uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
00040 {
00041 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
00042 }
00043
00044 uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
00045 {
00046 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
00047 }
00048
00049 void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
00050 uint16_t offset)
00051 {
00052 struct text_data *t = rtnl_ematch_data(e);
00053 t->cfg.to_offset = offset;
00054 t->cfg.to_layer = layer;
00055 }
00056
00057 uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
00058 {
00059 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
00060 }
00061
00062 uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
00063 {
00064 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
00065 }
00066
00067 void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
00068 char *pattern, size_t len)
00069 {
00070 struct text_data *t = rtnl_ematch_data(e);
00071
00072 if (t->pattern)
00073 free(t->pattern);
00074
00075 t->pattern = pattern;
00076 t->cfg.pattern_len = len;
00077 }
00078
00079 char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
00080 {
00081 return ((struct text_data *) rtnl_ematch_data(e))->pattern;
00082 }
00083
00084 size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
00085 {
00086 return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
00087 }
00088
00089 void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
00090 {
00091 struct text_data *t = rtnl_ematch_data(e);
00092
00093 strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo));
00094 }
00095
00096 char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
00097 {
00098 struct text_data *t = rtnl_ematch_data(e);
00099
00100 return t->cfg.algo[0] ? t->cfg.algo : NULL;
00101 }
00102
00103 static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
00104 {
00105 struct text_data *t = rtnl_ematch_data(e);
00106 size_t hdrlen = sizeof(struct tcf_em_text);
00107 size_t plen = len - hdrlen;
00108
00109 memcpy(&t->cfg, data, hdrlen);
00110
00111 if (t->cfg.pattern_len > plen)
00112 return -NLE_INVAL;
00113
00114 if (t->cfg.pattern_len > 0) {
00115 if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
00116 return -NLE_NOMEM;
00117
00118 memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len);
00119 }
00120
00121 return 0;
00122 }
00123
00124 static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
00125 {
00126 struct text_data *t = rtnl_ematch_data(e);
00127 char buf[64];
00128
00129 nl_dump(p, "text(%s \"%s\"",
00130 t->cfg.algo[0] ? t->cfg.algo : "no-algo",
00131 t->pattern ? : "no-pattern");
00132
00133 if (t->cfg.from_layer || t->cfg.from_offset) {
00134 nl_dump(p, " from %s",
00135 rtnl_ematch_offset2txt(t->cfg.from_layer,
00136 t->cfg.from_offset,
00137 buf, sizeof(buf)));
00138 }
00139
00140 if (t->cfg.to_layer || t->cfg.to_offset) {
00141 nl_dump(p, " to %s",
00142 rtnl_ematch_offset2txt(t->cfg.to_layer,
00143 t->cfg.to_offset,
00144 buf, sizeof(buf)));
00145 }
00146
00147 nl_dump(p, ")");
00148 }
00149
00150 static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
00151 {
00152 struct text_data *t = rtnl_ematch_data(e);
00153 int err;
00154
00155 if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
00156 return err;
00157
00158 return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
00159 }
00160
00161 static void text_free(struct rtnl_ematch *e)
00162 {
00163 struct text_data *t = rtnl_ematch_data(e);
00164 free(t->pattern);
00165 }
00166
00167 static struct rtnl_ematch_ops text_ops = {
00168 .eo_kind = TCF_EM_TEXT,
00169 .eo_name = "text",
00170 .eo_minlen = sizeof(struct tcf_em_text),
00171 .eo_datalen = sizeof(struct text_data),
00172 .eo_parse = text_parse,
00173 .eo_dump = text_dump,
00174 .eo_fill = text_fill,
00175 .eo_free = text_free,
00176 };
00177
00178 static void __init text_init(void)
00179 {
00180 rtnl_ematch_register(&text_ops);
00181 }
00182
00183