7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /* enable debug output and some debug asserts */
30 #undef _IPQOS_CONF_DEBUG
31
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <libintl.h>
35 #include <signal.h>
36 #include <strings.h>
37 #include <sys/nvpair.h>
38 #include <stdio.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <ctype.h>
42 #include <sys/socket.h>
43 #include <limits.h>
44 #include <netdb.h>
45 #include <fcntl.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <errno.h>
605 if (errno == ENOSPC &&
606 strcmp(action_name, IPGPC_CLASSIFY) == 0) {
607 ipqos_msg(MT_ERROR,
608 gettext("Max number of classes reached in %s.\n"),
609 IPGPC_NAME);
610
611 /* other errors */
612
613 } else {
614 ipqos_msg(MT_ERROR,
615 gettext("Failed to create class %s in action "
616 "%s: %s.\n"), class_name, action_name,
617 strerror(errno));
618 }
619
620 goto fail;
621 }
622
623 return (IPQOS_CONF_SUCCESS);
624 fail:
625 if (nvl != NULL)
626 nvlist_free(nvl);
627 return (IPQOS_CONF_ERR);
628 }
629
630
631 /*
632 * modify the class in the kernel action action_name called class_name with
633 * stats set according to stats_enable and the first action set to
634 * first_action.
635 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
636 */
637 static int
638 modify_class(
639 char *action_name,
640 char *class_name,
641 int module_version,
642 boolean_t stats_enable,
643 char *first_action,
644 enum ipp_flags flags)
645 {
694
695 /* add originator ipqosconf */
696 if (add_orig_ipqosconf(nvl) != IPQOS_CONF_SUCCESS) {
697 goto fail;
698 }
699
700 /* call lib to do modify */
701 if (ipp_action_modify(action_name, &nvl, flags) != 0) {
702
703 /* generic error message */
704
705 ipqos_msg(MT_ERROR,
706 gettext("Modifying class %s in action %s failed: %s.\n"),
707 class_name, action_name, strerror(errno));
708
709 goto fail;
710 }
711
712 return (IPQOS_CONF_SUCCESS);
713 fail:
714 if (nvl != NULL)
715 nvlist_free(nvl);
716 return (IPQOS_CONF_ERR);
717 }
718
719 /*
720 * removes the class class_name from the kernel action action_name. The
721 * flags argument can currently be set to IPP_ACTION_DESTROY which will
722 * result in the action this class references being destroyed.
723 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
724 */
725 static int
726 remove_class(
727 char *action_name,
728 char *class_name,
729 int module_version,
730 enum ipp_flags flags)
731 {
732
733 nvlist_t *nvl;
734
759
760 /* add class name */
761 if (nvlist_add_string(nvl, CLASSIFIER_CLASS_NAME, class_name) != 0) {
762 ipqos_msg(MT_ENOSTR, "nvlist_add_string");
763 goto fail;
764 }
765
766 if (ipp_action_modify(action_name, &nvl, flags) != 0) {
767
768 /* generic error message */
769
770 ipqos_msg(MT_ERROR,
771 gettext("Removing class %s in action %s failed: %s.\n"),
772 class_name, action_name, strerror(errno));
773
774 goto fail;
775 }
776
777 return (IPQOS_CONF_SUCCESS);
778 fail:
779 if (nvl != NULL)
780 nvlist_free(nvl);
781 return (IPQOS_CONF_ERR);
782 }
783
784 /*
785 * add the filter flt to the kernel action named action_name.
786 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
787 */
788 static int
789 add_filter(
790 char *action_name,
791 ipqos_conf_filter_t *flt,
792 int module_version)
793 {
794
795 nvlist_t *nvl = flt->nvlist;
796 char ipvsbuf[IPQOS_INT_STR_LEN];
797
798 IPQOSCDBG4(APPLY, "add_filter: action: %s, filter: %s, "
799 "instance: %d, class: %s\n", action_name, flt->name,
6328 class = malloc(sizeof (ipqos_conf_class_t));
6329 if (class) {
6330 bzero(class, sizeof (ipqos_conf_class_t));
6331 } else {
6332 ipqos_msg(MT_ENOSTR, "malloc");
6333 }
6334
6335 return (class);
6336 }
6337
6338 /* frees up all memory occupied by a filter struct and its contents. */
6339 static void
6340 free_class(ipqos_conf_class_t *cls)
6341 {
6342
6343 if (cls == NULL)
6344 return;
6345
6346 /* free its nvlist if present */
6347
6348 if (cls->nvlist)
6349 nvlist_free(cls->nvlist);
6350
6351 /* free its action refs if present */
6352
6353 if (cls->alist)
6354 free_arefs(cls->alist);
6355
6356 /* finally free class itself */
6357 free(cls);
6358 }
6359
6360 /*
6361 * Checks whether there is a class called class_nm in classes list.
6362 * RETURNS: ptr to first matched class, else if not matched NULL.
6363 */
6364 static ipqos_conf_class_t *
6365 classexist(
6366 char *class_nm,
6367 ipqos_conf_class_t *classes)
6368 {
6773 /* place at head of list */
6774
6775 aref->next = *arefs;
6776 *arefs = aref;
6777
6778 return (IPQOS_CONF_SUCCESS);
6779 }
6780
6781 /*
6782 * free all the memory used by the action references in arefs.
6783 */
6784 static void
6785 free_arefs(
6786 ipqos_conf_act_ref_t *arefs)
6787 {
6788
6789 ipqos_conf_act_ref_t *aref = arefs;
6790 ipqos_conf_act_ref_t *next;
6791
6792 while (aref) {
6793 if (aref->nvlist)
6794 nvlist_free(aref->nvlist);
6795 next = aref->next;
6796 free(aref);
6797 aref = next;
6798 }
6799 }
6800
6801
6802
6803 /* *************************************************************** */
6804
6805
6806
6807 /*
6808 * checks whether aname is a valid action name.
6809 * RETURNS: IPQOS_CONF_ERR if invalid, else IPQOS_CONF_SUCCESS.
6810 */
6811 static int
6812 valid_aname(char *aname)
6813 {
|
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* enable debug output and some debug asserts */
28 #undef _IPQOS_CONF_DEBUG
29
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <libintl.h>
33 #include <signal.h>
34 #include <strings.h>
35 #include <sys/nvpair.h>
36 #include <stdio.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include <ctype.h>
40 #include <sys/socket.h>
41 #include <limits.h>
42 #include <netdb.h>
43 #include <fcntl.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <errno.h>
603 if (errno == ENOSPC &&
604 strcmp(action_name, IPGPC_CLASSIFY) == 0) {
605 ipqos_msg(MT_ERROR,
606 gettext("Max number of classes reached in %s.\n"),
607 IPGPC_NAME);
608
609 /* other errors */
610
611 } else {
612 ipqos_msg(MT_ERROR,
613 gettext("Failed to create class %s in action "
614 "%s: %s.\n"), class_name, action_name,
615 strerror(errno));
616 }
617
618 goto fail;
619 }
620
621 return (IPQOS_CONF_SUCCESS);
622 fail:
623 nvlist_free(nvl);
624 return (IPQOS_CONF_ERR);
625 }
626
627
628 /*
629 * modify the class in the kernel action action_name called class_name with
630 * stats set according to stats_enable and the first action set to
631 * first_action.
632 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
633 */
634 static int
635 modify_class(
636 char *action_name,
637 char *class_name,
638 int module_version,
639 boolean_t stats_enable,
640 char *first_action,
641 enum ipp_flags flags)
642 {
691
692 /* add originator ipqosconf */
693 if (add_orig_ipqosconf(nvl) != IPQOS_CONF_SUCCESS) {
694 goto fail;
695 }
696
697 /* call lib to do modify */
698 if (ipp_action_modify(action_name, &nvl, flags) != 0) {
699
700 /* generic error message */
701
702 ipqos_msg(MT_ERROR,
703 gettext("Modifying class %s in action %s failed: %s.\n"),
704 class_name, action_name, strerror(errno));
705
706 goto fail;
707 }
708
709 return (IPQOS_CONF_SUCCESS);
710 fail:
711 nvlist_free(nvl);
712 return (IPQOS_CONF_ERR);
713 }
714
715 /*
716 * removes the class class_name from the kernel action action_name. The
717 * flags argument can currently be set to IPP_ACTION_DESTROY which will
718 * result in the action this class references being destroyed.
719 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
720 */
721 static int
722 remove_class(
723 char *action_name,
724 char *class_name,
725 int module_version,
726 enum ipp_flags flags)
727 {
728
729 nvlist_t *nvl;
730
755
756 /* add class name */
757 if (nvlist_add_string(nvl, CLASSIFIER_CLASS_NAME, class_name) != 0) {
758 ipqos_msg(MT_ENOSTR, "nvlist_add_string");
759 goto fail;
760 }
761
762 if (ipp_action_modify(action_name, &nvl, flags) != 0) {
763
764 /* generic error message */
765
766 ipqos_msg(MT_ERROR,
767 gettext("Removing class %s in action %s failed: %s.\n"),
768 class_name, action_name, strerror(errno));
769
770 goto fail;
771 }
772
773 return (IPQOS_CONF_SUCCESS);
774 fail:
775 nvlist_free(nvl);
776 return (IPQOS_CONF_ERR);
777 }
778
779 /*
780 * add the filter flt to the kernel action named action_name.
781 * RETURNS: IPQOS_CONF_ERR on error, else IPQOS_CONF_SUCCES.
782 */
783 static int
784 add_filter(
785 char *action_name,
786 ipqos_conf_filter_t *flt,
787 int module_version)
788 {
789
790 nvlist_t *nvl = flt->nvlist;
791 char ipvsbuf[IPQOS_INT_STR_LEN];
792
793 IPQOSCDBG4(APPLY, "add_filter: action: %s, filter: %s, "
794 "instance: %d, class: %s\n", action_name, flt->name,
6323 class = malloc(sizeof (ipqos_conf_class_t));
6324 if (class) {
6325 bzero(class, sizeof (ipqos_conf_class_t));
6326 } else {
6327 ipqos_msg(MT_ENOSTR, "malloc");
6328 }
6329
6330 return (class);
6331 }
6332
6333 /* frees up all memory occupied by a filter struct and its contents. */
6334 static void
6335 free_class(ipqos_conf_class_t *cls)
6336 {
6337
6338 if (cls == NULL)
6339 return;
6340
6341 /* free its nvlist if present */
6342
6343 nvlist_free(cls->nvlist);
6344
6345 /* free its action refs if present */
6346
6347 if (cls->alist)
6348 free_arefs(cls->alist);
6349
6350 /* finally free class itself */
6351 free(cls);
6352 }
6353
6354 /*
6355 * Checks whether there is a class called class_nm in classes list.
6356 * RETURNS: ptr to first matched class, else if not matched NULL.
6357 */
6358 static ipqos_conf_class_t *
6359 classexist(
6360 char *class_nm,
6361 ipqos_conf_class_t *classes)
6362 {
6767 /* place at head of list */
6768
6769 aref->next = *arefs;
6770 *arefs = aref;
6771
6772 return (IPQOS_CONF_SUCCESS);
6773 }
6774
6775 /*
6776 * free all the memory used by the action references in arefs.
6777 */
6778 static void
6779 free_arefs(
6780 ipqos_conf_act_ref_t *arefs)
6781 {
6782
6783 ipqos_conf_act_ref_t *aref = arefs;
6784 ipqos_conf_act_ref_t *next;
6785
6786 while (aref) {
6787 nvlist_free(aref->nvlist);
6788 next = aref->next;
6789 free(aref);
6790 aref = next;
6791 }
6792 }
6793
6794
6795
6796 /* *************************************************************** */
6797
6798
6799
6800 /*
6801 * checks whether aname is a valid action name.
6802 * RETURNS: IPQOS_CONF_ERR if invalid, else IPQOS_CONF_SUCCESS.
6803 */
6804 static int
6805 valid_aname(char *aname)
6806 {
|